From 540b341051c778e00b00a03a6621f0a0f6988d0c Mon Sep 17 00:00:00 2001 From: Anthony Perkins Date: Thu, 18 Jul 2019 13:43:28 +0100 Subject: [PATCH] Add back vimoutliner --- pack/acp/start/vimoutliner/.gitignore | 16 + pack/acp/start/vimoutliner/CHANGELOG | 1556 +++++++++++++++++ pack/acp/start/vimoutliner/INSTALL | 137 ++ pack/acp/start/vimoutliner/LICENSE | 11 + pack/acp/start/vimoutliner/README | 81 + pack/acp/start/vimoutliner/README.detailed | 1 + pack/acp/start/vimoutliner/TODO.otl | 27 + .../start/vimoutliner/colors/votl_dark.vim | 81 + .../start/vimoutliner/colors/votl_light.vim | 81 + .../start/vimoutliner/colors/votl_test.vim | 81 + pack/acp/start/vimoutliner/doc/votl.txt | 1331 ++++++++++++++ .../start/vimoutliner/doc/votl_cheatsheet.txt | 85 + pack/acp/start/vimoutliner/ftdetect/votl.vim | 26 + pack/acp/start/vimoutliner/ftplugin/votl.vim | 679 +++++++ pack/acp/start/vimoutliner/install.sh | 173 ++ pack/acp/start/vimoutliner/syntax/votl.vim | 248 +++ .../vimoutliner/images/Vimoutliner_logo.png | Bin 0 -> 19060 bytes .../images/Vimoutliner_logo_tiny.png | Bin 0 -> 7036 bytes .../vimoutliner/images/favicon.ico | Bin 0 -> 318 bytes .../vimoutliner/plugin/prev/votl_hoist.otl | 77 + .../vimoutliner/plugin/prev/votl_hoist.vim | 251 +++ .../vimoutliner/plugin/votl_checkbox.otl | 310 ++++ .../vimoutliner/plugin/votl_checkbox.vim | 475 +++++ .../vimoutliner/plugin/votl_clock.vim | 139 ++ .../vimoutliner/plugin/votl_format.vim | 157 ++ .../vimoutliner/plugin/votl_gtd.vim | 219 +++ .../vimoutliner/plugin/votl_math.otl | 56 + .../vimoutliner/plugin/votl_math.vim | 286 +++ .../vimoutliner/plugin/votl_newhoist.vim | 456 +++++ .../vimoutliner/plugin/votl_smart_paste.vim | 117 ++ .../vimoutliner/plugin/votl_tags.vim | 246 +++ .../vimoutliner/scripts/MediaWiki2otl | 17 + .../vimoutliner/scripts/MediaWiki2otl.desc | 37 + .../vimoutliner/scripts/Node/COPYING | 118 ++ .../vimoutliner/scripts/Node/COPYING.GPL | 340 ++++ .../scripts/Node/COPYING.LPDTL.1.0 | 118 ++ .../vimoutliner/scripts/Node/INSTALL | 23 + .../scripts/Node/LPDTL_discuss.txt | 26 + .../vimoutliner/scripts/Node/Node.pm | 475 +++++ .../vimoutliner/scripts/Node/README.otl | 177 ++ .../vimoutliner/scripts/Node/deletetest.otl | 18 + .../scripts/Node/example_attribs.pl | 162 ++ .../scripts/Node/example_bylevel.pl | 227 +++ .../scripts/Node/example_delete.pl | 107 ++ .../vimoutliner/scripts/Node/example_hello.pl | 15 + .../scripts/Node/example_insert.pl | 550 ++++++ .../scripts/Node/example_nodepath.pl | 135 ++ .../scripts/Node/example_otl2markup.pl | 123 ++ .../vimoutliner/scripts/Node/example_parse.pl | 114 ++ .../vimoutliner/scripts/Node/myapp.cfg | 4 + .../vimoutliner/vimoutliner/scripts/fs2otl | 7 + .../vimoutliner/scripts/otl2aft.awk | 284 +++ .../vimoutliner/scripts/otl2aft.pdf | Bin 0 -> 82163 bytes .../vimoutliner/scripts/otl2docbook.pl | 270 +++ .../vimoutliner/scripts/otl2html.py | 1111 ++++++++++++ .../scripts/otl2html_autonumbered.css | 269 +++ .../vimoutliner/scripts/otl2html_nnnnnn.css | 246 +++ .../vimoutliner/scripts/otl2latex/.vimrc | 44 + .../vimoutliner/scripts/otl2latex/README | 23 + .../scripts/otl2latex/otl2latex.otl | 95 + .../scripts/otl2latex/otl2latex.pdf | Bin 0 -> 102839 bytes .../scripts/otl2latex/otl2latex.png | Bin 0 -> 42112 bytes .../scripts/otl2latex/otl2latex.py | 315 ++++ .../scripts/otl2latex/otl2latex.tex | 223 +++ .../scripts/otl2latex/otl2latex.toc | 9 + .../vimoutliner/scripts/otl2lyx.awk | 149 ++ .../vimoutliner/scripts/otl2ooimpress.py | 263 +++ .../vimoutliner/scripts/otl2ooimpress.sh | 34 + .../vimoutliner/scripts/otl2table.py | 199 +++ .../vimoutliner/scripts/otl2tags.py | 713 ++++++++ .../scripts/otl2tags_freemind.conf | 96 + .../scripts/otl2tags_graphviz.conf | 104 ++ .../scripts/otl_handler/Apache/OTL.pm | 324 ++++ .../vimoutliner/scripts/otl_handler/README | 155 ++ .../scripts/otl_handler/devel-mode | 5 + .../scripts/otl_handler/javascript/jquery.js | 12 + .../scripts/otl_handler/javascript/theme2.js | 38 + .../scripts/otl_handler/javascript/theme3.js | 22 + .../scripts/otl_handler/sample.otl | 39 + .../scripts/otl_handler/styles/theme1.css | 88 + .../scripts/otl_handler/styles/theme2.css | 152 ++ .../scripts/otl_handler/styles/theme3.css | 109 ++ .../vimoutliner/scripts/otlgrep.py | 212 +++ .../vimoutliner/scripts/otlhead.sh | 12 + .../vimoutliner/scripts/otlsplit.py | 191 ++ .../vimoutliner/scripts/otltail.sh | 15 + .../scripts/outline_calendar/2005.otl | 1472 ++++++++++++++++ .../scripts/outline_calendar/vimrc | 31 + .../outline_calendar/vo_calendar_ctags.conf | 9 + .../outline_calendar/vo_calendar_generator.rb | 110 ++ .../outline_calendar/vo_calendar_readme.otl | 195 +++ .../outline_calendar/vo_calendar_shelf.otl | 6 + .../outline_calendar/vo_calendar_ui.sh | 39 + .../scripts/outline_freemind/freemind.py | 198 +++ .../outline_freemind/freemind_outline.py | 48 + .../scripts/outline_freemind/otl.py | 26 + .../outline_freemind/outline_freemind.py | 114 ++ .../scripts/outline_freemind/test.otl | 27 + .../scripts/outline_freemind/test.sh | 10 + .../vimoutliner/scripts/vo2html.rb | 329 ++++ .../vimoutliner/vimoutliner/scripts/vo2odp.rb | 415 +++++ .../vimoutliner/vimoutliner/scripts/vo2xo.rb | 239 +++ .../vimoutliner/scripts/votl_maketags.1 | 50 + .../vimoutliner/scripts/votl_maketags.pl | 338 ++++ pack/acp/start/vimoutliner/vimoutlinerrc | 67 + 105 files changed, 19740 insertions(+) create mode 100644 pack/acp/start/vimoutliner/.gitignore create mode 100644 pack/acp/start/vimoutliner/CHANGELOG create mode 100644 pack/acp/start/vimoutliner/INSTALL create mode 100644 pack/acp/start/vimoutliner/LICENSE create mode 100644 pack/acp/start/vimoutliner/README create mode 120000 pack/acp/start/vimoutliner/README.detailed create mode 100644 pack/acp/start/vimoutliner/TODO.otl create mode 100644 pack/acp/start/vimoutliner/colors/votl_dark.vim create mode 100644 pack/acp/start/vimoutliner/colors/votl_light.vim create mode 100644 pack/acp/start/vimoutliner/colors/votl_test.vim create mode 100644 pack/acp/start/vimoutliner/doc/votl.txt create mode 100644 pack/acp/start/vimoutliner/doc/votl_cheatsheet.txt create mode 100644 pack/acp/start/vimoutliner/ftdetect/votl.vim create mode 100644 pack/acp/start/vimoutliner/ftplugin/votl.vim create mode 100755 pack/acp/start/vimoutliner/install.sh create mode 100644 pack/acp/start/vimoutliner/syntax/votl.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/images/Vimoutliner_logo.png create mode 100644 pack/acp/start/vimoutliner/vimoutliner/images/Vimoutliner_logo_tiny.png create mode 100644 pack/acp/start/vimoutliner/vimoutliner/images/favicon.ico create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.otl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.otl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_clock.vim create mode 100755 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_format.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_gtd.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_newhoist.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_smart_paste.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/plugin/votl_tags.vim create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl.desc create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.GPL create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.LPDTL.1.0 create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/INSTALL create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/LPDTL_discuss.txt create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/Node.pm create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/README.otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/deletetest.otl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_attribs.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_bylevel.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_delete.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_hello.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_insert.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_nodepath.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_otl2markup.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_parse.pl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/Node/myapp.cfg create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/fs2otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.awk create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.pdf create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2docbook.pl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html.py create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_autonumbered.css create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_nnnnnn.css create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/.vimrc create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/README create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.pdf create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.png create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.py create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.tex create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.toc create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2lyx.awk create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.py create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.sh create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2table.py create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2tags.py create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2tags_freemind.conf create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl2tags_graphviz.conf create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/Apache/OTL.pm create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/README create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/devel-mode create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/jquery.js create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/theme2.js create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/theme3.js create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/sample.otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme1.css create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme2.css create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme3.css create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otlgrep.py create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otlhead.sh create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otlsplit.py create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/otltail.sh create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/2005.otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vimrc create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ctags.conf create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_generator.rb create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_readme.otl create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_shelf.otl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ui.sh create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind.py create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind_outline.py create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/otl.py create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/outline_freemind.py create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.otl create mode 100755 pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.sh create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/vo2html.rb create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/vo2odp.rb create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/vo2xo.rb create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.1 create mode 100644 pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.pl create mode 100644 pack/acp/start/vimoutliner/vimoutlinerrc diff --git a/pack/acp/start/vimoutliner/.gitignore b/pack/acp/start/vimoutliner/.gitignore new file mode 100644 index 0000000..fdc5844 --- /dev/null +++ b/pack/acp/start/vimoutliner/.gitignore @@ -0,0 +1,16 @@ +# Vim +*.sw? +*.un? +tags + +# archives +*.zip +*.gz +*.gzip + +# osx noise +.DS_Store + +# Python +*.pyc +*~ diff --git a/pack/acp/start/vimoutliner/CHANGELOG b/pack/acp/start/vimoutliner/CHANGELOG new file mode 100644 index 0000000..3b52f7d --- /dev/null +++ b/pack/acp/start/vimoutliner/CHANGELOG @@ -0,0 +1,1556 @@ +CHANGELOG + + +Version 0.4.0 +Updated 2014-10-19 + * Additions/Changes: + - Added a list-based tags feature similar to org-mode + - Complete rewrite of the outline math plugin. + - Added colorscheme option to vimoutlinerrc and directory + - Modified to install.sh to: 1. Turn off backup functionality. + 2. Remove old backup clutter. 3. Remove old vo_base.vim files from + syntax, ftdetect and ftpluginAdd VimOutliner icons to the repository. + - Updated TODO.otl + - Move README.detailed to doc/votl.txt to make Pathogen working. + - Added information on pathogen installation to INSTALL file. + - Added syntax conceal for math equations. Concealed equations appear + as µ + - Add VimOutliner icons to the repository + - Add votl_maketags manpage + * Bug fixes: + - Small corrections and updates + - Removed unnecessary reserved mappings + - doc/votl_readme.txt is just a copy of old votl.txt, removed it. + - Fix for user-defined for command mappings. + - Moved loading of .vimoutlinerrc to before key mappings, other fixes + - Update in install.sh so that it installs vimoutlinerrc correctly. + - Correct votl_cheatsheet so that it is installed with helptags. + - Gramatical and stylistic corrections. + - Remove all remainders of localleader munging. + - Removed vimball install instructions from INSTALL and README files. + - Fix Help links + - Fix FSF address + + +Version 0.3.7 +Released 2014-04-05 + * Additions/Changes: + - Added new hoisting plugin. + - Added new tags plugin. + - Add weighted checkboxes. + - Now checkboxes calculations will ignore dash ([-]) marked items. + - Added new math plugin. + - Merged new clock plugin. + - Added new format plugin. + - Added new gtd plugin. + - Added updated smart_paste plugin. + - Added otl2latex script with files. + - New file type naming convention: vo_base to votl. + - Color fixes and updates. + - Updated vimoutlinerrc with more options for new plugins. + - Moved previous hoist plugin to prev directory, + - Made new TODO list + - Uploaded MediaWiki2otl script. + - Updated documentation. + * Bug fixes: + - Stop setting global options. + - Fixed checkboxes calculation to make it faster and more consistent. + - Strtime fix in vo_base.vim + - Corrections to READNE.detailed, readme, INSTALL and cheatsheet files. + - Corrections to install.sh. + - Replaced len() so it works with multibyte chars. + +Version 0.3.6 +Released 2011-05-09 + * Additions/Changes: + - Added updated comments and information to the user in the INSTALL + file. + - Added comments and information to the user in install.sh to align + with the new version. + - Added new light version of README and moved the more extensive file + to README.detailed + - Several updates and additions to the README, README.detailed and + doc/vo_readme.txt file. + * Bug fixes: + - Source only the first vimoutlinerrc found. + - Do not echo mappings. + - Fixed typo and updated reference in install.sh. + - Fixed several typos and updated reference in the + ftplugin/vo_base.vim + - Fixed typos and removed outdated references in the vo_hoist.otl and + vo_hoist.vim files. + - Fixed typos and removed outdated references in the vo_checkbox.otl + file. + - Fixed two mappings for sourcing rc file and writing file in + ftplugin/vo_base.vim. + - Fixed typos in colors/vo_base.vim + - Fixed errors when g:vo_modules_load is not defined, also updated the + plugin loading process to use lists. + +Version 0.3.5 +Released 2011-03-20 + * Additions/Changes: + - Moved all files inside $HOME/.vim. + - Added a cheat sheet to the documentation. + - Added smart-paste plugin. + - Added and updated post-processor scripts: + · fs2otl + · Node.pm + · otl2aft.awk + · otl2docbook.pl + · otl2html.py + · otl2lyx.awk + · otl2ooimpress.py + · otl2table.py + · otl2tags.py + · otlgrep.py + · otlhead.sh + · otlsplit.py + · otltail.sh + · otl_handler + · outline_calendar + · outline_freemind + · vo_maketags.pl + - Added syntax support for _ilink_. + - Hoist plugin disabled by default. + - Layout of vo_readme.txt made more similar to Vim help. + * Bug fixes: + - ,,S did not work. Fixed + +Version 0.3.4 +Released + * Additions/changes: + - added ,,cp as an alias to ,,c% + - Color schemes have been added + - Checkboxes and hoisting default to 'on' + - Modified ,,cb and ,,c% (and ,,cp) to work only on headings + - Fixed the ,,cz command to make the correct call + - Added descriptions of VO objects to help (headings, text, tables, + etc.) + * Bug fixes: + - W18 errors have been fixed + +============================================================================= +RCS file: /root/VimOutliner/VimOutliner/INSTALL,v +Working file: INSTALL +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2004-11-27 19:30:43 +0000; author: noel; state: Exp; lines: +2 -2 + +Minor syntax and installation adjustments. +Change to vo_checkbox to fix a typo. +---------------------------- +revision 1.1 +date: 2004-02-17 22:00:15 +0000; author: noel; state: Exp; +These files are only in cvs for backup purposes. They should be extracted +from vo_readme.txt and never edited themselves: + INSTALL + LICENSE + VERSION +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/Attic/INSTALL.TXT,v +Working file: INSTALL.TXT +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +Quick installation instructions for developers. +---------------------------- +revision 1.3 +date: 2003-06-20 14:13:15 +0000; author: noel; state: dead; lines: +0 -0 +Final documentation tweaks for the final 0.3.0 release. +---------------------------- +revision 1.2 +date: 2003-06-18 13:50:55 +0000; author: noel; state: Exp; lines: +1 -1 +Modified the installation title. +---------------------------- +revision 1.1 +date: 2003-03-20 22:56:49 +0000; author: noel; state: Exp; +Initial revision +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/LICENSE,v +Working file: LICENSE +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2004-11-27 19:30:43 +0000; author: noel; state: Exp; lines: +4 -2 + +Minor syntax and installation adjustments. +Change to vo_checkbox to fix a typo. +---------------------------- +revision 1.1 +date: 2004-02-17 22:00:15 +0000; author: noel; state: Exp; +These files are only in cvs for backup purposes. They should be extracted +from vo_readme.txt and never edited themselves: + INSTALL + LICENSE + VERSION +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/VERSION,v +Working file: VERSION +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 4 +description: +---------------------------- +revision 1.4 +date: 2005-06-07 17:48:50 +0000; author: noel; state: Exp; lines: +4 -0 +Updated to include help on VO objects. +---------------------------- +revision 1.3 +date: 2005-06-07 17:41:42 +0000; author: noel; state: Exp; lines: +10 -10 +Updated version. +---------------------------- +revision 1.2 +date: 2004-11-27 19:30:43 +0000; author: noel; state: Exp; lines: +9 -14 + +Minor syntax and installation adjustments. +Change to vo_checkbox to fix a typo. +---------------------------- +revision 1.1 +date: 2004-02-17 22:00:15 +0000; author: noel; state: Exp; +These files are only in cvs for backup purposes. They should be extracted +from vo_readme.txt and never edited themselves: + INSTALL + LICENSE + VERSION +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/install.sh,v +Working file: install.sh +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1.3 +date: 2005-06-06 18:42:29 +0000; author: noel; state: Exp; lines: +3 -0 +Added support for color schemes. +---------------------------- +revision 1.2 +date: 2004-11-27 19:30:43 +0000; author: noel; state: Exp; lines: +2 -2 + +Minor syntax and installation adjustments. +Change to vo_checkbox to fix a typo. +---------------------------- +revision 1.1 +date: 2004-05-02 19:03:01 +0000; author: noel; state: Exp; +Added to the distro. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/vimoutlinerrc,v +Working file: vimoutlinerrc +head: 1.6 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 6; selected revisions: 6 +description: +---------------------------- +revision 1.6 +date: 2005-06-07 12:39:01 +0000; author: noel; state: Exp; lines: +9 -78 +Enabled checkboxes and hoisting by default. +Added Vim colorscheme support. +---------------------------- +revision 1.5 +date: 2005-01-19 15:06:20 +0000; author: noel; state: Exp; lines: +4 -3 +Fixed another W18 error. +Enabled hoisting and checkboxes by default. +---------------------------- +revision 1.4 +date: 2004-05-24 15:56:34 +0000; author: noel; state: Exp; lines: +45 -0 +Added highlighting and folding support for: + Tables (marked with '|') + User-defined, wrapping text (marked with '>') + User-defined, non-wrapping text (marked with '<') +---------------------------- +revision 1.3 +date: 2004-05-17 17:27:55 +0000; author: noel; state: Exp; lines: +2 -2 +Fixed plugin loaders for checkboxes and hoisting. +---------------------------- +revision 1.2 +date: 2004-03-18 13:23:53 +0000; author: noel; state: Exp; lines: +1 -0 +Added a line to change the background. +---------------------------- +revision 1.1 +date: 2004-02-17 21:50:36 +0000; author: noel; state: Exp; +This file will be provided from now on to make it easy for people +to customize their settings. The install process will rename this file +to .vimoutlinerrc and put it into the user's home directory. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/Attic/vo_INSTALL.TXT,v +Working file: vo_INSTALL.TXT +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2005-06-07 17:24:05 +0000; author: noel; state: dead; lines: +0 -0 +*** empty log message *** +---------------------------- +revision 1.1 +date: 2003-06-26 19:52:07 +0000; author: noel; state: Exp; +Initial add to VimOutliner +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/Attic/vo_README.otl,v +Working file: vo_README.otl +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 4 +description: +---------------------------- +revision 1.4 +date: 2005-06-07 17:24:05 +0000; author: noel; state: dead; lines: +0 -0 +*** empty log message *** +---------------------------- +revision 1.3 +date: 2003-10-17 02:17:07 +0000; author: noel; state: Exp; lines: +2 -2 +Changed version numbers. +---------------------------- +revision 1.2 +date: 2003-06-20 14:13:15 +0000; author: noel; state: Exp; lines: +4 -41 +Final documentation tweaks for the final 0.3.0 release. +---------------------------- +revision 1.1 +date: 2003-06-18 13:55:03 +0000; author: noel; state: Exp; +Added this documentation to Vim Outliner. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/add-ons/plugins/vo_checkbox.otl,v +Working file: add-ons/plugins/vo_checkbox.otl +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1.3 +date: 2004-11-27 19:30:43 +0000; author: noel; state: Exp; lines: +12 -8 + +Minor syntax and installation adjustments. +Change to vo_checkbox to fix a typo. +---------------------------- +revision 1.2 +date: 2004-05-17 15:57:58 +0000; author: noel; state: Exp; lines: +6 -0 +Modified documentation to match current version. +---------------------------- +revision 1.1 +date: 2003-10-23 22:13:00 +0000; author: noel; state: Exp; +Instructions for vo_checkbox.vim +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/add-ons/plugins/vo_checkbox.vim,v +Working file: add-ons/plugins/vo_checkbox.vim +head: 1.18 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 18; selected revisions: 18 +description: +---------------------------- +revision 1.18 +date: 2005-06-07 15:08:59 +0000; author: noel; state: Exp; lines: +12 -45 +Fixed a bug that added checkboxes to body text, preformatted body text, +tables, user-defined text and user-defined preformatted text lines. +Fixed a bug where ,,cb would modify terms like 'test%' or ',,c%'. Now +it only modifies this term: ' [0-9]*%'. +---------------------------- +revision 1.17 +date: 2005-06-07 13:53:22 +0000; author: noel; state: Exp; lines: +8 -2 +Added ,,cp. It is the same as ,,c% +---------------------------- +revision 1.16 +date: 2004-05-27 22:22:48 +0000; author: noel; state: Exp; lines: +24 -4 +Made ,,cd smart so it would try to delete non-existent checkboxes. +Fixed a recursion bug in NewHMD to branches with a single child would +be computed properly. +---------------------------- +revision 1.15 +date: 2004-05-27 18:11:53 +0000; author: noel; state: Exp; lines: +25 -5 +Added smart (only the entire tree in which the child exists), automatic +completion calculations to the ,,cx command. +Added smart (only for parents, not children) '%' sign insertion for +,,c%. +---------------------------- +revision 1.14 +date: 2004-05-17 15:53:38 +0000; author: noel; state: Exp; lines: +13 -7 +Modified SwitchBox() to be more selective. +---------------------------- +revision 1.13 +date: 2004-05-17 15:43:23 +0000; author: noel; state: Exp; lines: +7 -3 +Fixed a broken key mapping: ,,c%. +---------------------------- +revision 1.12 +date: 2004-02-23 12:19:27 +0000; author: noel; state: Exp; lines: +26 -9 +Fixed Up-to-date problem. +Fixed 'Safely script names'. +---------------------------- +revision 1.11 +date: 2003-09-05 16:37:55 +0000; author: cepl; state: Exp; lines: +41 -2 +Added ,cp binding for the new function InsertCheckBoxPerCent, +which adds not only the checkbox but also percentage sign. +---------------------------- +revision 1.10 +date: 2003-08-23 16:42:15 +0000; author: noel; state: Exp; lines: +18 -17 +Modified completion percentages to be recursive. +This: +[_] 0% Project + [_] 33% Task + [_] Subtask + [X] Subtask + [X] Subtask + [_] 0% Task + [_] Subtask + [_] 50% Subtask + [X] Subsubtask + [_] Subsubtask + [X] Subsubtask + [_] Subsubtask + +Becomes this: +[_] 29% Project + [_] 33% Task + [_] Subtask + [X] Subtask + [X] Subtask + [_] 25% Task + [_] Subtask + [_] 50% Subtask + [X] Subsubtask + [_] Subsubtask + [X] Subsubtask + [_] Subsubtask +---------------------------- +revision 1.9 +date: 2003-08-16 13:49:53 +0000; author: noel; state: Exp; lines: +9 -7 +added ! to functions. +---------------------------- +revision 1.8 +date: 2003-08-11 19:16:28 +0000; author: noel; state: Exp; lines: +30 -5 +Fixed a bug in which any line that contained the letter x was counted as +completed. +---------------------------- +revision 1.7 +date: 2003-08-03 23:56:46 +0000; author: noel; state: Exp; lines: +89 -40 + +Replaced HowManyDone() with a new routine. The new routine is recursive, +ignores headings that don't have checkboxes and does not care what the +current folding states of the parent or children are. The heading at the +top of the tree does not even need to have a checkbox. This will work: + +Projects + [_] Software + [_] Input + [_] Processing + [_] Math + [_] Database + [_] Networking + [_] Output + [_] Hardware + [_] Keyboard + [_] Harddisk + [_] Processor + [_] Printer + +One only needs to ,,cx on Projects to update everything (everything shown). +As before, including a % on a parent heading with childred, will be replaced +with a percentage of completion. Nice work Matej! +---------------------------- +revision 1.6 +date: 2003-07-14 00:36:57 +0000; author: noel; state: Exp; lines: +9 -5 +Changed [x] to [X] to make it look more full. If the consensus is +[x], I'll gladly put it back. +---------------------------- +revision 1.5 +date: 2003-07-10 16:29:50 +0000; author: cepl; state: Exp; lines: +75 -3 +Calculation of the subtree completion added. The very first alpha +draft. +---------------------------- +revision 1.4 +date: 2003-07-08 23:48:43 +0000; author: noel; state: Exp; lines: +6 -3 +Fixed a bug in cd. It used to only delete unchecked boxes. +Now it does both. +---------------------------- +revision 1.3 +date: 2003-07-07 14:17:04 +0000; author: noel; state: Exp; lines: +11 -6 +Fixed the folding of the new headers. +---------------------------- +revision 1.2 +date: 2003-07-07 14:14:02 +0000; author: noel; state: Exp; lines: +24 -0 +Added appropriate headers. +---------------------------- +revision 1.1 +date: 2003-07-07 13:52:45 +0000; author: noel; state: Exp; +Changed checkbox.vim to vo_checkbox.vim +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/add-ons/plugins/vo_hoist.otl,v +Working file: add-ons/plugins/vo_hoist.otl +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2003-10-23 22:12:20 +0000; author: noel; state: Exp; +Instructions for vo_hoist.vim. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/add-ons/plugins/vo_hoist.vim,v +Working file: add-ons/plugins/vo_hoist.vim +head: 1.9 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 9; selected revisions: 9 +description: +---------------------------- +revision 1.9 +date: 2003-11-12 17:26:09 +0000; author: noel; state: Exp; lines: +6 -2 +Added a command to place the cursor on the first line of +a hoisted outline. +---------------------------- +revision 1.8 +date: 2003-11-12 17:10:51 +0000; author: noel; state: Exp; lines: +9 -3 +Fixed a bug that occurs on a level 1 heading with no children. +---------------------------- +revision 1.7 +date: 2003-10-23 22:14:14 +0000; author: noel; state: Exp; lines: +13 -5 +Minor changes to DeHoist() to compensate for current foldlevel settings. +---------------------------- +revision 1.6 +date: 2003-08-17 15:35:24 +0000; author: noel; state: Exp; lines: +10 -9 +Put the new mappings in the correct place this time. +Added a : and to the ZZ command. +---------------------------- +revision 1.5 +date: 2003-08-17 14:47:42 +0000; author: noel; state: Exp; lines: +8 -2 +Added ZZ, qa, and x to the list of commands that de-hoist the current +outline. +---------------------------- +revision 1.4 +date: 2003-08-17 00:07:31 +0000; author: noel; state: Exp; lines: +13 -10 +Added "silent" to commands generating tedious messages. +---------------------------- +revision 1.3 +date: 2003-08-16 20:08:06 +0000; author: noel; state: Exp; lines: +11 -6 +Removed a need to exclude fold level 1 headings. +---------------------------- +revision 1.2 +date: 2003-08-16 19:02:44 +0000; author: noel; state: Exp; lines: +84 -31 +First fully functional version. May need some tweaks but it works and is +quite easy to use. +---------------------------- +revision 1.1 +date: 2003-08-14 21:05:05 +0000; author: noel; state: Exp; +First publicly available, experiment verison +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/colors/vo_dark.vim,v +Working file: colors/vo_dark.vim +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2005-06-07 15:24:30 +0000; author: noel; state: Exp; lines: +1 -1 +The color darkyellow does not appear to exist on some systems. This color +has been changed to darkred. +---------------------------- +revision 1.1 +date: 2005-06-06 18:45:11 +0000; author: noel; state: Exp; +These are the new color scheme files. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/colors/vo_light.vim,v +Working file: colors/vo_light.vim +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2005-06-07 15:24:30 +0000; author: noel; state: Exp; lines: +3 -3 +The color darkyellow does not appear to exist on some systems. This color +has been changed to darkred. +---------------------------- +revision 1.1 +date: 2005-06-06 18:45:11 +0000; author: noel; state: Exp; +These are the new color scheme files. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/doc/vo_readme.txt,v +Working file: doc/vo_readme.txt +head: 1.9 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 9; selected revisions: 9 +description: +---------------------------- +revision 1.9 +date: 2005-06-07 17:48:21 +0000; author: noel; state: Exp; lines: +4 -0 +Added a better VERSION description. +---------------------------- +revision 1.8 +date: 2005-06-07 16:44:58 +0000; author: noel; state: Exp; lines: +294 -150 +Added a section about VO objects. +Added the ,,cp command. +---------------------------- +revision 1.7 +date: 2004-05-28 15:28:47 +0000; author: noel; state: Exp; lines: +274 -28 +Added complete help for vo_checkbox.vim. +---------------------------- +revision 1.6 +date: 2004-05-17 17:16:28 +0000; author: noel; state: Exp; lines: +1 -1 +Changed 0.3.2 to 0.3.3 in the tite. +---------------------------- +revision 1.5 +date: 2004-05-17 15:21:25 +0000; author: noel; state: Exp; lines: +75 -69 +Modified to reflecte 0.3.3 changes. +---------------------------- +revision 1.4 +date: 2004-02-17 21:52:41 +0000; author: noel; state: Exp; lines: +263 -111 +Modified heavily by Stefan Schiedl for 0.3.2. +---------------------------- +revision 1.3 +date: 2003-10-17 02:18:07 +0000; author: noel; state: Exp; lines: +44 -7 +Changed version numbers. +---------------------------- +revision 1.2 +date: 2003-06-20 14:13:15 +0000; author: noel; state: Exp; lines: +5 -42 +Final documentation tweaks for the final 0.3.0 release. +---------------------------- +revision 1.1 +date: 2003-06-18 13:55:03 +0000; author: noel; state: Exp; +Added this documentation to Vim Outliner. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/experimental/Attic/checkbox.vim,v +Working file: experimental/checkbox.vim +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2003-07-07 13:52:45 +0000; author: noel; state: dead; lines: +0 -0 +Changed checkbox.vim to vo_checkbox.vim +---------------------------- +revision 1.1 +date: 2003-07-07 01:22:35 +0000; author: noel; state: Exp; +Initial experimental version of checkboxes. +Contains only one function and two mappings. +The only capabilities are to add and delete check boxes from +the beginnings of headings. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/filetype/Attic/filetype.vim,v +Working file: filetype/filetype.vim +head: 1.5 +branch: +locks: strict +access list: +symbolic names: + arelease: 1.1.1.1 + avendor: 1.1.1 + testfork: 1.3.0.2 +keyword substitution: kv +total revisions: 6; selected revisions: 6 +description: +VimOutliner filetype.vim +---------------------------- +revision 1.5 +date: 2005-06-07 17:26:52 +0000; author: noel; state: dead; lines: +5 -2 +*** empty log message *** +---------------------------- +revision 1.4 +date: 2003-03-01 17:37:17 +0000; author: noel; state: Exp; lines: +6 -3 +Changed the filetype name to our new standard: vo_base +---------------------------- +revision 1.3 +date: 2003-02-14 17:49:43 +0000; author: noel; state: Exp; lines: +6 -4 +Removed unnecessary filetype commands +---------------------------- +revision 1.2 +date: 2003-02-09 15:07:35 +0000; author: noel; state: Exp; lines: +8 -7 +Changed the auto commands. Setting the "filetype plugin indent on" +option here does not work with ftplugins. +---------------------------- +revision 1.1 +date: 2003-02-08 21:11:26 +0000; author: noel; state: Exp; +branches: 1.1.1; +Initial revision +---------------------------- +revision 1.1.1.1 +date: 2003-03-20 22:35:15 +0000; author: noel; state: Exp; lines: +17 -8 +no message +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/filetype/vo_base.vim,v +Working file: filetype/vo_base.vim +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2005-01-19 16:12:37 +0000; author: noel; state: Exp; +Finally added to CVS. +Don't know how I missed this one. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/ftplugin/vo_base.vim,v +Working file: ftplugin/vo_base.vim +head: 2.59 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 59; selected revisions: 59 +description: +Vim Outliner Main Program File +---------------------------- +revision 2.59 +date: 2005-06-07 19:50:45 +0000; author: noel; state: Exp; lines: +2 -1 +Re-removed the did_filetype() function. Restored the original variable-based +solution. +---------------------------- +revision 2.58 +date: 2005-06-07 12:47:38 +0000; author: noel; state: Exp; lines: +1 -2 +Modified switch that prevents the filetype from being loaded more than once. +---------------------------- +revision 2.57 +date: 2004-05-24 22:31:11 +0000; author: noel; state: Exp; lines: +0 -6 +Removed a redundant PreformattedBodyText() function. +---------------------------- +revision 2.56 +date: 2004-05-24 15:56:34 +0000; author: noel; state: Exp; lines: +78 -0 +Added highlighting and folding support for: + Tables (marked with '|') + User-defined, wrapping text (marked with '>') + User-defined, non-wrapping text (marked with '<') +---------------------------- +revision 2.55 +date: 2004-05-17 15:18:20 +0000; author: noel; state: Exp; lines: +20 -1 +Added Steve Litt's simple executable lines. +---------------------------- +revision 2.54 +date: 2004-05-17 14:18:27 +0000; author: noel; state: Exp; lines: +41 -16 +Replaced system calls to 'date' with strftime(). +Modified the time- and date-stamp functions. +normal t append the time to the current heading +normal T prepend the time to the current heading +insert t insert the time at the cursor +normal d append the date to the current heading +normal D prepend the date to the current heading +insert d insert the date at the cursor +---------------------------- +revision 2.53 +date: 2004-05-17 13:32:38 +0000; author: noel; state: Exp; lines: +2 -2 +Added to end of sort commands. +---------------------------- +revision 2.52 +date: 2004-05-17 13:30:12 +0000; author: noel; state: Exp; lines: +167 -2 +Added child-aware sorting functions. +Mapped s to sort ascending. +Mapped S to sort descending. +---------------------------- +revision 2.51 +date: 2004-03-18 13:25:46 +0000; author: noel; state: Exp; lines: +1 -1 +Fixed a mapping command for w +---------------------------- +revision 2.50 +date: 2004-02-17 21:47:31 +0000; author: noel; state: Exp; lines: +0 -217 +Removed the detailed revision log. It's getting too big. From now on +'cvs log' will need to be used to see the log. +---------------------------- +revision 2.49 +date: 2003-10-17 01:37:10 +0000; author: noel; state: Exp; lines: +24 -10 +Fixed a minor folding issue. +---------------------------- +revision 2.48 +date: 2003-08-04 13:25:17 +0000; author: noel; state: Exp; lines: +37 -7 +Corrected a type for w +---------------------------- +revision 2.47 +date: 2003-06-16 23:57:20 +0000; author: noel; state: Exp; lines: +7 -3 +Set UseSpaceColon=0. This is now the standard. +---------------------------- +revision 2.46 +date: 2003-06-04 11:54:25 +0000; author: noel; state: Exp; lines: +24 -6 +The behavior of the "d" and "t" commands have been improved and put into +functions. These commands are now mapped to call the improved functions. +---------------------------- +revision 2.45 +date: 2003-06-04 11:25:56 +0000; author: noel; state: Exp; lines: +12 -3 +Moved the modification to the tags path outside the "if" statement in +autocommands in ftplugin. Completely removed the line from syntax. +---------------------------- +revision 2.44 +date: 2003-05-27 13:33:34 +0000; author: noel; state: Exp; lines: +45 -29 +Added Vim style folds to both vo_base files to make them easier to read. +Added a mode line to the end of each to activate the folds. +Added a "Documentation" section that is mostly empty. This section will +eventually be extracted automatically to form the online help via Vim's +built-in help mechanisms. +---------------------------- +revision 2.43 +date: 2003-05-23 18:36:44 +0000; author: noel; state: Exp; lines: +7 -4 +More trouble with the ,,d function and retaining proper indentation. +---------------------------- +revision 2.42 +date: 2003-05-23 16:02:42 +0000; author: noel; state: Exp; lines: +8 -2 +Added tag file support for ~/.vimoutliner. +---------------------------- +revision 2.41 +date: 2003-05-23 13:55:25 +0000; author: noel; state: Exp; lines: +10 -6 +Modified the d and t commands. They did not work properly on closed folds. +Commented-out the d and t commands when in insert mode. I have not used them +and they don't work properly. +---------------------------- +revision 2.40 +date: 2003-05-17 23:29:25 +0000; author: noel; state: Exp; lines: +11 -6 +Modified date and time (,,d/,,t) to place date/time at beginning of +line instead of end of line to allow for sorting. +---------------------------- +revision 2.39 +date: 2003-05-17 22:49:26 +0000; author: noel; state: Exp; lines: +20 -16 +Changed ^M to in all occurrances. +Modified date (d) and time (t) to add date/time to end of +current line. +---------------------------- +revision 2.38 +date: 2003-03-05 17:58:22 +0000; author: cepl; state: Exp; lines: +6 -3 +Personal configuration file was not run from the user's $HOME directory. +Fixed. +---------------------------- +revision 2.37 +date: 2003-03-03 16:24:49 +0000; author: noel; state: Exp; lines: +6 -3 +Added ~/.vim and ~/.vimoutliner as places to look for tag files. +---------------------------- +revision 2.36 +date: 2003-03-01 17:37:41 +0000; author: noel; state: Exp; lines: +13 -5 +Changed the filetype name to our new standard: vo_base +---------------------------- +revision 2.35 +date: 2003-02-09 15:04:56 +0000; author: noel; state: Exp; lines: +70 -55 +Changed key mappings to be local to the current buffer only. They +will also be loaded for any subsequent .otl file. +Changed key mappings to use an easily modifiable leader. In this case +",,". +Changed the scope of some variables. They had a buffer scoping but now +have a function scope. +---------------------------- +revision 2.34 +date: 2003-02-08 22:07:47 +0000; author: noel; state: Exp; lines: +5 -63 +Removed spellfix functions. Perhaps I'll make them another plugin. +---------------------------- +revision 2.33 +date: 2003-02-08 21:31:01 +0000; author: noel; state: Exp; lines: +5 -116 +Split out syntax settings as Dillon originally showed. +---------------------------- +revision 2.32 +date: 2003-01-30 01:47:41 +0000; author: noel; state: Exp; lines: +6 -3 +modified switches sent to ispell to make it guess better. +---------------------------- +revision 2.31 +date: 2003-01-28 22:31:37 +0000; author: noel; state: Exp; lines: +6 -3 +Modified setlocal foldtext.... to set foldtext.... +---------------------------- +revision 2.30 +date: 2003-01-22 22:03:12 +0000; author: noel; state: Exp; lines: +8 -3 +Fixed bodytext folding method. +---------------------------- +revision 2.29 +date: 2003-01-21 00:18:50 +0000; author: noel; state: Exp; lines: +20 -7 +Fixed a problem with runtimepath. +Added a use_space_colon setting to that one can choose between bodytext +marked with a : or with a space-:. +---------------------------- +revision 2.28 +date: 2003-01-19 16:46:27 +0000; author: noel; state: Exp; lines: +11 -3 +Removed some strange escape characters from a revision comment. +---------------------------- +revision 2.27 +date: 2003-01-19 16:16:54 +0000; author: noel; state: Exp; lines: +101 -88 +Added detection of the color scheme and an alternative set of colors +for dark backgrounds. (well actually for non-"light" backgrounds) at +Dillon Jones' request. +Set the "current_syntax" at Dillon's request. +Modified the exe lines in the source to remove the debugging style I was +using. +---------------------------- +revision 2.26 +date: 2003-01-16 00:56:51 +0000; author: noel; state: Exp; lines: +26 -23 +Changed a bunch of set commands to setlocal commands at the +suggestion of Jeffrey Hood. Thanks, Jeffrey! +---------------------------- +revision 2.25 +date: 2003-01-13 17:05:08 +0000; author: noel; state: Exp; lines: +14 -11 +Fixed a problem with the new regex that define headings. +---------------------------- +revision 2.24 +date: 2003-01-12 19:08:32 +0000; author: noel; state: Exp; lines: +36 -25 +Converted from _ to : +---------------------------- +revision 2.23 +date: 2003-01-11 21:00:33 +0000; author: noel; state: Exp; lines: +55 -38 +Added Matej requirement for personalization settings via +.vimoutlinerrc. +Added Steve's style of bodytext that allows for wrapping and formatting +with have the headings wrap as well. It is currently set for "_" as +the bodytext marker. +Added ,,b to set all bodytext to Steve's style. +Added ,,B to set all bodytext to my style. This will also make it +possible for Steve's style to be quickly reformatted for pretty +printing with :ha. +---------------------------- +revision 2.22 +date: 2003-01-11 00:35:32 +0000; author: noel; state: Exp; lines: +7 -2 +[6~Added support for .vimoutlinerrc in both ~ and ~/.vimoutliner. +---------------------------- +revision 2.21 +date: 2002-12-12 13:38:58 +0000; author: noel; state: Exp; lines: +10 -3 +Fixed a spelling problem when words contain a '. +---------------------------- +revision 2.20 +date: 2002-12-11 23:33:16 +0000; author: noel; state: Exp; lines: +7 -3 +Removed a debug setting, again (sigh). +Added some iskeyword symbols so spell-check would work on things +like: don't +---------------------------- +revision 2.19 +date: 2002-12-11 22:55:19 +0000; author: noel; state: Exp; lines: +24 -11 +Fixed body text end error. I was checking for too specific a case. +---------------------------- +revision 2.18 +date: 2002-12-11 14:57:52 +0000; author: noel; state: Exp; lines: +7 -4 +Fixed wrapmargin setting and a line counter error during folding. +---------------------------- +revision 2.17 +date: 2002-12-11 00:42:47 +0000; author: noel; state: Exp; lines: +7 -3 +Removed a debug setting, again. +---------------------------- +revision 2.16 +date: 2002-12-10 22:21:09 +0000; author: noel; state: Exp; lines: +19 -14 +Moved body text up one tab level. It seems to be more intuitive +to others. +---------------------------- +revision 2.15 +date: 2002-12-10 19:24:13 +0000; author: noel; state: Exp; lines: +6 -2 +Added a function to auto-wrap lines. This could be a problem for entering long headings. +---------------------------- +revision 2.14 +date: 2002-12-10 18:11:13 +0000; author: noel; state: Exp; lines: +9 -3 +Removed a debug feature +---------------------------- +revision 2.13 +date: 2002-12-10 17:59:42 +0000; author: noel; state: Exp; lines: +45 -15 +Added bodytext. +Added bodytext folding. +Modified MyFoldText to show [TEXT] for folded bodytext. +Added an autocommand to re-sync the folding. +---------------------------- +revision 2.12 +date: 2002-12-09 18:16:49 +0000; author: noel; state: Exp; lines: +11 -4 +Fixed a typo and added an extra \ before & for adding upper cas3e +words. +---------------------------- +revision 2.11 +date: 2002-12-09 17:15:37 +0000; author: noel; state: Exp; lines: +13 -5 +Added ,,kA. +Swapped functions of ,,ka and ,,kA. + ,,ka add lowercase version of word to dictionary + ,,kA add word as it appears to dictionary +---------------------------- +revision 2.10 +date: 2002-12-09 17:08:47 +0000; author: noel; state: Exp; lines: +15 -8 +Fixed an error that occurs when there is just a single spelling checker. +---------------------------- +revision 2.9 +date: 2002-12-09 16:42:02 +0000; author: noel; state: Exp; lines: +13 -7 +Fixed error messages on searches with no matches. +This is part of the spell-check search. +---------------------------- +revision 2.8 +date: 2002-12-09 14:21:29 +0000; author: noel; state: Exp; lines: +11 -8 +Fixed spelling highlighting and and spelling searches so that only real matches are highlighed and possible to jump to with ,,kn and ,,kN (and n and N after +that). +Modified the "source" statement that load spellfix.vim. Spellfix.vim now +needs to be in ~/.vimoutliner. +---------------------------- +revision 2.7 +date: 2002-12-07 22:08:02 +0000; author: noel; state: Exp; lines: +30 -39 +finished integration of spellfix.vim +---------------------------- +revision 2.6 +date: 2002-12-07 16:46:47 +0000; author: noel; state: Exp; lines: +86 -6 +Added these commands to enhance the spelling checker + ,,kk speck-check document highlighting errors + ,,ka add the word under the cursor to the selected dictionary + ,,kn search forward to the next spelling error + N and n both work well with this + ,,kN search backward to the next spelling error + N and n both work well with this + ,,kq unhighlight the spelling errors +---------------------------- +revision 2.5 +date: 2002-11-27 22:54:28 +0000; author: noel; state: Exp; lines: +22 -16 +Changed date and time formats. +changed the mappings of ,,0-,,9 so that ,,1 corresponds to show only +1 level. +---------------------------- +revision 2.4 +date: 2002-11-26 00:36:08 +0000; author: noel; state: Exp; lines: +68 -62 +Added more comments. +Added Steve's GPL header. +Will keep the RCS info in my version but will remove it for +distribution. +---------------------------- +revision 2.3 +date: 2002-11-21 19:30:37 +0000; author: noel; state: Exp; lines: +21 -8 +Included a patchfile from Steve to: + move the if loaded behavior to a place in the file after the settings + add an if loaded behavior for the file extension autocommmand + added the nocindent setting + changed the ,,,, mapping + clear the indexexpr setting +---------------------------- +revision 2.2 +date: 2002-11-16 00:00:10 +0000; author: noel; state: Exp; lines: +215 -196 +Added more comments. +Switched the polarity of the if exists(loaded_outliner) function +Commented-out some experimental features. +Grouped the user preferences together and separated out the +VimOutliner operational settings. +---------------------------- +revision 2.1 +date: 2002-11-15 23:37:39 +0000; author: noel; state: Exp; +Version 2 Beta Candidate before pre-release modifications +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/otf/otf.vim,v +Working file: otf/otf.vim +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1.3 +date: 2003-06-03 19:56:09 +0000; author: gabriel; state: Exp; lines: +2 -2 +changed bash function to perl,corrected file name error in otf.vi +---------------------------- +revision 1.2 +date: 2003-06-02 21:01:16 +0000; author: gabriel; state: Exp; lines: +9 -9 +created wishlist_demo.otl +changed output files of Createotl() in otf.vim so users need only a ~/bin directory +---------------------------- +revision 1.1 +date: 2003-06-01 13:16:32 +0000; author: gabriel; state: Exp; +new 'on the fly' files +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/otf/otfREADME,v +Working file: otf/otfREADME +head: 1.4 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 4; selected revisions: 4 +description: +---------------------------- +revision 1.4 +date: 2003-06-03 20:21:43 +0000; author: gabriel; state: Exp; lines: +2 -1 +instruction where to put otl.pl +---------------------------- +revision 1.3 +date: 2003-06-03 19:56:09 +0000; author: gabriel; state: Exp; lines: +2 -3 +changed bash function to perl,corrected file name error in otf.vi +---------------------------- +revision 1.2 +date: 2003-06-02 21:01:16 +0000; author: gabriel; state: Exp; lines: +12 -7 +created wishlist_demo.otl +changed output files of Createotl() in otf.vim so users need only a ~/bin directory +---------------------------- +revision 1.1 +date: 2003-06-01 13:16:32 +0000; author: gabriel; state: Exp; +new 'on the fly' files +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/otf/otl,v +Working file: otf/otl +head: 1.2 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 2; selected revisions: 2 +description: +---------------------------- +revision 1.2 +date: 2003-06-02 21:01:16 +0000; author: gabriel; state: Exp; lines: +2 -5 +created wishlist_demo.otl +changed output files of Createotl() in otf.vim so users need only a ~/bin directory +---------------------------- +revision 1.1 +date: 2003-06-01 13:16:32 +0000; author: gabriel; state: Exp; +new 'on the fly' files +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/otf/otl.pl,v +Working file: otf/otl.pl +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2003-06-03 19:57:00 +0000; author: gabriel; state: Exp; +new script replacing otl +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/otf/wishlist_demo.otl,v +Working file: otf/wishlist_demo.otl +head: 1.3 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 3; selected revisions: 3 +description: +---------------------------- +revision 1.3 +date: 2003-06-03 20:21:43 +0000; author: gabriel; state: Exp; lines: +2 -1 +instruction where to put otl.pl +---------------------------- +revision 1.2 +date: 2003-06-02 21:29:49 +0000; author: gabriel; state: Exp; lines: +28 -18 +changed Otl fns branch so it had the correct parents +---------------------------- +revision 1.1 +date: 2003-06-02 21:01:16 +0000; author: gabriel; state: Exp; +created wishlist_demo.otl +changed output files of Createotl() in otf.vim so users need only a ~/bin directory +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/scripts/vo_maketags.pl,v +Working file: scripts/vo_maketags.pl +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2003-06-20 14:13:15 +0000; author: noel; state: Exp; +Final documentation tweaks for the final 0.3.0 release. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/syntax/vo_base.vim,v +Working file: syntax/vo_base.vim +head: 2.47 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 47; selected revisions: 47 +description: +Vim Outliner Main Program File +---------------------------- +revision 2.47 +date: 2005-06-07 15:24:30 +0000; author: noel; state: Exp; lines: +4 -4 +The color darkyellow does not appear to exist on some systems. This color +has been changed to darkred. +---------------------------- +revision 2.46 +date: 2005-01-19 15:03:55 +0000; author: noel; state: Exp; lines: +2 -1 +Fixed another W18 error. +---------------------------- +revision 2.45 +date: 2004-11-27 19:30:43 +0000; author: noel; state: Exp; lines: +6 -5 + +Minor syntax and installation adjustments. +Change to vo_checkbox to fix a typo. +---------------------------- +revision 2.44 +date: 2004-05-24 15:56:34 +0000; author: noel; state: Exp; lines: +142 -19 +Added highlighting and folding support for: + Tables (marked with '|') + User-defined, wrapping text (marked with '>') + User-defined, non-wrapping text (marked with '<') +---------------------------- +revision 2.43 +date: 2004-02-17 21:48:47 +0000; author: noel; state: Exp; lines: +0 -297 +Removed the embedded and out-of-date documentation. +Removed the detailed revision log. It's too large. From now on +'cvs log' will be needed to see the log. +---------------------------- +revision 2.42 +date: 2003-10-17 01:34:03 +0000; author: noel; state: Exp; lines: +43 -30 + +Modified highlighting to support extended character sets. +---------------------------- +revision 2.41 +date: 2003-06-04 11:25:56 +0000; author: noel; state: Exp; lines: +5 -3 +Moved the modification to the tags path outside the "if" statement in +autocommands in ftplugin. Completely removed the line from syntax. +---------------------------- +revision 2.40 +date: 2003-05-27 15:03:26 +0000; author: noel; state: Exp; lines: +88 -23 +Added some documentation on the commands. +---------------------------- +revision 2.39 +date: 2003-05-27 13:33:34 +0000; author: noel; state: Exp; lines: +73 -16 +Added Vim style folds to both vo_base files to make them easier to read. +Added a mode line to the end of each to activate the folds. +Added a "Documentation" section that is mostly empty. This section will +eventually be extracted automatically to form the online help via Vim's +built-in help mechanisms. +---------------------------- +revision 2.38 +date: 2003-05-23 16:02:42 +0000; author: noel; state: Exp; lines: +8 -3 +Added tag file support for ~/.vimoutliner. +---------------------------- +revision 2.37 +date: 2003-03-01 17:07:53 +0000; author: noel; state: Exp; lines: +34 -36 +Removed the bold and underline glamour. +It did not work with the level colorization nor properly cross line boundries. +---------------------------- +revision 2.36 +date: 2003-02-12 15:40:26 +0000; author: noel; state: Exp; lines: +41 -32 +Added some glamour. *word* make word bold and _word_ underlines a word. +---------------------------- +revision 2.35 +date: 2003-02-09 14:54:10 +0000; author: noel; state: Exp; lines: +7 -3 +Removed syntax highlighting for SpellErrors and BadWord. The plugins +include their own. +---------------------------- +revision 2.34 +date: 2003-02-08 21:59:25 +0000; author: noel; state: Exp; lines: +36 -31 +Added SpellErrors and BadWord to the contains attributes of headings +and bodytext. Now we're compatible with engspchk and vimspell. +---------------------------- +revision 2.33 +date: 2003-02-08 21:34:46 +0000; author: noel; state: Exp; lines: +5 -213 +Split out functions as Dillon originally showed. +---------------------------- +revision 2.32 +date: 2003-01-30 01:47:41 +0000; author: noel; state: Exp; lines: +6 -3 +modified switches sent to ispell to make it guess better. +---------------------------- +revision 2.31 +date: 2003-01-28 22:31:37 +0000; author: noel; state: Exp; lines: +6 -3 +Modified setlocal foldtext.... to set foldtext.... +---------------------------- +revision 2.30 +date: 2003-01-22 22:03:12 +0000; author: noel; state: Exp; lines: +8 -3 +Fixed bodytext folding method. +---------------------------- +revision 2.29 +date: 2003-01-21 00:18:50 +0000; author: noel; state: Exp; lines: +20 -7 +Fixed a problem with runtimepath. +Added a use_space_colon setting to that one can choose between bodytext +marked with a : or with a space-:. +---------------------------- +revision 2.28 +date: 2003-01-19 16:46:27 +0000; author: noel; state: Exp; lines: +11 -3 +Removed some strange escape characters from a revision comment. +---------------------------- +revision 2.27 +date: 2003-01-19 16:16:54 +0000; author: noel; state: Exp; lines: +101 -88 +Added detection of the color scheme and an alternative set of colors +for dark backgrounds. (well actually for non-"light" backgrounds) at +Dillon Jones' request. +Set the "current_syntax" at Dillon's request. +Modified the exe lines in the source to remove the debugging style I was +using. +---------------------------- +revision 2.26 +date: 2003-01-16 00:56:51 +0000; author: noel; state: Exp; lines: +26 -23 +Changed a bunch of set commands to setlocal commands at the +suggestion of Jeffrey Hood. Thanks, Jeffrey! +---------------------------- +revision 2.25 +date: 2003-01-13 17:05:08 +0000; author: noel; state: Exp; lines: +14 -11 +Fixed a problem with the new regex that define headings. +---------------------------- +revision 2.24 +date: 2003-01-12 19:08:32 +0000; author: noel; state: Exp; lines: +36 -25 +Converted from _ to : +---------------------------- +revision 2.23 +date: 2003-01-11 21:00:33 +0000; author: noel; state: Exp; lines: +55 -38 +Added Matej requirement for personalization settings via +.vimoutlinerrc. +Added Steve's style of bodytext that allows for wrapping and formatting +with have the headings wrap as well. It is currently set for "_" as +the bodytext marker. +Added ,,b to set all bodytext to Steve's style. +Added ,,B to set all bodytext to my style. This will also make it +possible for Steve's style to be quickly reformatted for pretty +printing with :ha. +---------------------------- +revision 2.22 +date: 2003-01-11 00:35:32 +0000; author: noel; state: Exp; lines: +7 -2 +[6~Added support for .vimoutlinerrc in both ~ and ~/.vimoutliner. +---------------------------- +revision 2.21 +date: 2002-12-12 13:38:58 +0000; author: noel; state: Exp; lines: +10 -3 +Fixed a spelling problem when words contain a '. +---------------------------- +revision 2.20 +date: 2002-12-11 23:33:16 +0000; author: noel; state: Exp; lines: +7 -3 +Removed a debug setting, again (sigh). +Added some iskeyword symbols so spell-check would work on things +like: don't +---------------------------- +revision 2.19 +date: 2002-12-11 22:55:19 +0000; author: noel; state: Exp; lines: +24 -11 +Fixed body text end error. I was checking for too specific a case. +---------------------------- +revision 2.18 +date: 2002-12-11 14:57:52 +0000; author: noel; state: Exp; lines: +7 -4 +Fixed wrapmargin setting and a line counter error during folding. +---------------------------- +revision 2.17 +date: 2002-12-11 00:42:47 +0000; author: noel; state: Exp; lines: +7 -3 +Removed a debug setting, again. +---------------------------- +revision 2.16 +date: 2002-12-10 22:21:09 +0000; author: noel; state: Exp; lines: +19 -14 +Moved body text up one tab level. It seems to be more intuitive +to others. +---------------------------- +revision 2.15 +date: 2002-12-10 19:24:13 +0000; author: noel; state: Exp; lines: +6 -2 +Added a function to auto-wrap lines. This could be a problem for entering long headings. +---------------------------- +revision 2.14 +date: 2002-12-10 18:11:13 +0000; author: noel; state: Exp; lines: +9 -3 +Removed a debug feature +---------------------------- +revision 2.13 +date: 2002-12-10 17:59:42 +0000; author: noel; state: Exp; lines: +45 -15 +Added bodytext. +Added bodytext folding. +Modified MyFoldText to show [TEXT] for folded bodytext. +Added an autocommand to re-sync the folding. +---------------------------- +revision 2.12 +date: 2002-12-09 18:16:49 +0000; author: noel; state: Exp; lines: +11 -4 +Fixed a typo and added an extra \ before & for adding upper cas3e +words. +---------------------------- +revision 2.11 +date: 2002-12-09 17:15:37 +0000; author: noel; state: Exp; lines: +13 -5 +Added ,,kA. +Swapped functions of ,,ka and ,,kA. + ,,ka add lowercase version of word to dictionary + ,,kA add word as it appears to dictionary +---------------------------- +revision 2.10 +date: 2002-12-09 17:08:47 +0000; author: noel; state: Exp; lines: +15 -8 +Fixed an error that occurs when there is just a single spelling checker. +---------------------------- +revision 2.9 +date: 2002-12-09 16:42:02 +0000; author: noel; state: Exp; lines: +13 -7 +Fixed error messages on searches with no matches. +This is part of the spell-check search. +---------------------------- +revision 2.8 +date: 2002-12-09 14:21:29 +0000; author: noel; state: Exp; lines: +11 -8 +Fixed spelling highlighting and and spelling searches so that only real matches are highlighed and possible to jump to with ,,kn and ,,kN (and n and N after +that). +Modified the "source" statement that load spellfix.vim. Spellfix.vim now +needs to be in ~/.vimoutliner. +---------------------------- +revision 2.7 +date: 2002-12-07 22:08:02 +0000; author: noel; state: Exp; lines: +30 -39 +finished integration of spellfix.vim +---------------------------- +revision 2.6 +date: 2002-12-07 16:46:47 +0000; author: noel; state: Exp; lines: +86 -6 +Added these commands to enhance the spelling checker + ,,kk speck-check document highlighting errors + ,,ka add the word under the cursor to the selected dictionary + ,,kn search forward to the next spelling error + N and n both work well with this + ,,kN search backward to the next spelling error + N and n both work well with this + ,,kq unhighlight the spelling errors +---------------------------- +revision 2.5 +date: 2002-11-27 22:54:28 +0000; author: noel; state: Exp; lines: +22 -16 +Changed date and time formats. +changed the mappings of ,,0-,,9 so that ,,1 corresponds to show only +1 level. +---------------------------- +revision 2.4 +date: 2002-11-26 00:36:08 +0000; author: noel; state: Exp; lines: +68 -62 +Added more comments. +Added Steve's GPL header. +Will keep the RCS info in my version but will remove it for +distribution. +---------------------------- +revision 2.3 +date: 2002-11-21 19:30:37 +0000; author: noel; state: Exp; lines: +21 -8 +Included a patchfile from Steve to: + move the if loaded behavior to a place in the file after the settings + add an if loaded behavior for the file extension autocommmand + added the nocindent setting + changed the ,,,, mapping + clear the indexexpr setting +---------------------------- +revision 2.2 +date: 2002-11-16 00:00:10 +0000; author: noel; state: Exp; lines: +215 -196 +Added more comments. +Switched the polarity of the if exists(loaded_outliner) function +Commented-out some experimental features. +Grouped the user preferences together and separated out the +VimOutliner operational settings. +---------------------------- +revision 2.1 +date: 2002-11-15 23:37:39 +0000; author: noel; state: Exp; +Version 2 Beta Candidate before pre-release modifications +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/tarballs/vimoutliner-0.3.2.tar.gz,v +Working file: tarballs/vimoutliner-0.3.2.tar.gz +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2004-02-23 12:34:28 +0000; author: noel; state: Exp; +Adding for posterity's sake. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/tarballs/vimoutliner-0.3.2a.tar.gz,v +Working file: tarballs/vimoutliner-0.3.2a.tar.gz +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2004-02-23 12:34:28 +0000; author: noel; state: Exp; +Adding for posterity's sake. +============================================================================= + +RCS file: /root/VimOutliner/VimOutliner/tarballs/vimoutliner.0.3.1.tgz,v +Working file: tarballs/vimoutliner.0.3.1.tgz +head: 1.1 +branch: +locks: strict +access list: +symbolic names: +keyword substitution: kv +total revisions: 1; selected revisions: 1 +description: +---------------------------- +revision 1.1 +date: 2003-10-17 02:21:28 +0000; author: noel; state: Exp; +Official version 0.3.1 +============================================================================= + +" vim600: set noet ts=8 sw=8 sts=8 tw=78: diff --git a/pack/acp/start/vimoutliner/INSTALL b/pack/acp/start/vimoutliner/INSTALL new file mode 100644 index 0000000..c3e71c8 --- /dev/null +++ b/pack/acp/start/vimoutliner/INSTALL @@ -0,0 +1,137 @@ +Installing and Testing VimOutliner + + + Automatic Method |vo-auto-install| + Updating |vo-updating| + Manual Method |vo-manual-install| + Testing |vo-testing| + + +Automatic Method + +The automatic installation targets Unix-compatible platforms: + +From tar archive + + $ tar xzvf vimoutliner-0.3.x.tar.gz + $ cd vimoutliner + $ sh install.sh + +From zip archive + + $ unzip vimoutliner-0.3.x.zip + $ cd vimoutliner-0.3.x + $ sh install.sh + +Installing with pathogen + +If you have pathogen installed as your package manager you can clone the git repository in you +pathogen directory: + $ cd ~/.vim/bundle && git clone https://github.com/vimoutliner/vimoutliner.git + +Installing using install.sh: + +First you can decide whether to install the VimOutliner files or abort the +process leaving everything unchanged. Assuming you confirmed the +installation, the script creates the necessary directory tree and copies the +files which provide the core functionality and documentation. + +With the second question you decide whether you want to install some brand new +add-ons, currently implementing checkboxes(enabled), hoisting(disabled) +and smart paste(disabled), as well as several useful external scripts in the vimoutliner/scripts folder. + + +Updating + +Updating an existing installation might require some manual work. + +If you are already working with a previous VimOutliner release, there is a +slight chance that the current directory tree is different from your current +one. In this case, you will have to manually migrate your files to the new +locations. + +The installation script creates unique backups of files being replaced with +newer versions. So if you put some local customisations into, say +$HOME/.vim/vimoutliner/vimoutlinerrc, you'll probably have to merge the backup +with the new file by hand. + + +Manual Method + +You can also copy the files from the unpacked distribution tarball into their +destination folders by yourself. The following steps are a description of what +has to go where and assume some knowledge of your vim setup. + +If you encounter problems, please contact the mailing list for an immediate +solution and more complete future documentation. www.lists.vimoutliner.org + +If you want to setup VimOutliner on a system running Microsoft Windows, the +directory $HOME denotes the base folder of the vim installation. If you're on +Unix based system, $HOME is as usual. + +You need the following sub trees in your $HOME directory: + + $HOME/.vim/ + doc/ + ftdetect/ + ftplugin/ + syntax/ + vimoutliner/ + plugins/ + scripts/ + +The distribution tarball unpacks into a directory vimoutliner with the +following contents: + + vimoutliner/ + plugins/ (1) + scripts/ (1) + doc/ (1) + ftdetect/ (1) + ftplugin/ (1) + install.sh* + syntax/ (1) + syntax/ (1) + vimoutlinerrc (1) + +(1) The content of these folders should be copied to their namesakes in the +$HOME/.vim folder + +Your $HOME/.vimrc file should contain the lines + + filetype plugin indent on + syntax on + +Finally, you need to integrate the online help provided with VimOutliner into +the vim help system. Start vim and execute the following command: + + :helptags $HOME/.vim/doc + +At this point, VimOutliner should be functional. Type ":help vo" to get +started. To get a quick overview of all VimOutliner commands you can view the +cheatsheet with ":help votl_cheatsheet". + +Testing Base Functionality + +Create a text file and save it as a .otl file like vo_test.otl. Enter +some text and verify the following: +- Tabs indent the text +- Different indent levels are different colors +- Lines starting with a colon and space word-wrap + +Lines starting with colons are body text. They should word wrap and +should be a special color (typically green, but it can vary). Verify +that paragraphs of body text can be reformatted with the Vim gq +commands. + +You can test the different VimOutliner commands by looking at the examples +in the cheatsheet. "help votl_cheatsheet". + +Debian Installation + +Debian does include VimOutliner as a package. However some Debian versions +require this line to be added to your .vimrc file: + + syntax on + + diff --git a/pack/acp/start/vimoutliner/LICENSE b/pack/acp/start/vimoutliner/LICENSE new file mode 100644 index 0000000..e260844 --- /dev/null +++ b/pack/acp/start/vimoutliner/LICENSE @@ -0,0 +1,11 @@ +LICENSE + + VimOutliner + Copyright (C) 2001, 2003 by Steve Litt + Copyright (C) 2004 by Noel Henson + Licensed under the GNU General Public License (GPL), version 3 + Absolutely no warranty. + + If your distro doesn't come with the GPL file you can find it here: + HTML: http://www.gnu.org/copyleft/gpl.html + Text: http://www.gnu.org/copyleft/gpl.txt diff --git a/pack/acp/start/vimoutliner/README b/pack/acp/start/vimoutliner/README new file mode 100644 index 0000000..addfde3 --- /dev/null +++ b/pack/acp/start/vimoutliner/README @@ -0,0 +1,81 @@ + +VimOutliner README file + +Introduction + +VimOutliner is an outline processor with many of the same features +as Grandview, More, Thinktank, Ecco, etc. Features include tree +expand/collapse, tree promotion/demotion, level sensitive colors, +interoutline linking, and body text. + +What sets VimOutliner apart from the rest is that it's been constructed +from the ground up for fast and easy authoring. Keystrokes are quick and +easy, especially for someone knowing the Vim editor. VimOutliner can be +used without the mouse (but is supported to the extent that Vim supports +the mouse). + +Many of the VimOutliner commands start with a double comma ",," because +that's very quick to type. All VimOutliner files have the ".otl" +extension. For help on VimOutliner type ":h vo". For an overview of +all the most important VimOutliner commands you can type ":h votl_cheatsheet" +when you have opened an otl file. + + +* Usage + +VimOutliner has been reported to help with the following tasks: + + - Project management + - Password wallet + - To-do lists + - Account and cash book + - 'Plot device' for writing novels + - Inventory control + - Hierarchical database + - Web site management + +* Characteristics + + - Fast and effective + - Fully integrated with Vim + - Extensible through plugins + - Many post-processing scripts allow exporting to multiple formats + - Extensive documentation + +For more information on the use of VimOutliner see the README.detailed +file in this directory. + + +Installation details + +1. Zip file + +To install from the zip file do the following (exchange "x" with +version number from the package you have downloaded): + +$ unzip vimoutliner-0.3.x.zip $ cd vimoutliner-0.3.x $ sh install.sh + +2. Gzip archive + +To install from the gzip archive follow these steps: + +$ tar -xzvf vimoutliner-0.3.x.tgz $ cd vimoutliner-0.3.x $ sh install.sh + +Downloads + +zip archives are available here: + +https://github.com/vimoutliner/vimoutliner/downloads + +Download of all packages can also be done from the Freshmeat site: + +http://freecode.com/projects/vimoutliner + +For more detailed installation instructions see the INSTALL file in +this directory. + + + + + + diff --git a/pack/acp/start/vimoutliner/README.detailed b/pack/acp/start/vimoutliner/README.detailed new file mode 120000 index 0000000..5b34fec --- /dev/null +++ b/pack/acp/start/vimoutliner/README.detailed @@ -0,0 +1 @@ +doc/votl.txt \ No newline at end of file diff --git a/pack/acp/start/vimoutliner/TODO.otl b/pack/acp/start/vimoutliner/TODO.otl new file mode 100644 index 0000000..933fa04 --- /dev/null +++ b/pack/acp/start/vimoutliner/TODO.otl @@ -0,0 +1,27 @@ +TODO LIST + Updated: 20140916 + :This is just a preliminary roadmap, use the issue list at + :https://github.com/vimoutliner/vimoutliner/issues for suggesting new + :features and register issues or bugs + +Work planned for next version: + Cleanup code in plugins to more efficient vim script + Make plug mappings for all commands + Decide on common script language, and write scripts in new language + +Maybe/probably: + Include a list of vim plugins that are useful with VimOutliner + Templates + More sort functionality + Wiki plugin and documentation + Documentation on how to convert VO files to mindmap programs, Grapviz and Lyx + More colorschemes + vimoutliner-tutor + Documentation on how to use VO for writing + MetaData? + +Done: + Remove included RCS,logs etc. + + + diff --git a/pack/acp/start/vimoutliner/colors/votl_dark.vim b/pack/acp/start/vimoutliner/colors/votl_dark.vim new file mode 100644 index 0000000..a5d9868 --- /dev/null +++ b/pack/acp/start/vimoutliner/colors/votl_dark.vim @@ -0,0 +1,81 @@ +let g:colors_name="VO Dark" +hi normal guifg=white guibg=black ctermfg=gray ctermbg=black +hi StatusLine guifg=white guibg=black ctermfg=gray ctermbg=black +hi StatusLineNC guifg=white guibg=black ctermfg=gray ctermbg=black +hi VertSplit guifg=white guibg=black ctermfg=gray ctermbg=black +hi OL1 guifg=white ctermfg=gray +hi OL2 guifg=red ctermfg=darkred +hi OL3 guifg=lightblue ctermfg=darkblue +hi OL4 guifg=violet ctermfg=darkmagenta +hi OL5 guifg=white ctermfg=gray +hi OL6 guifg=red ctermfg=darkred +hi OL7 guifg=lightblue ctermfg=darkblue +hi OL8 guifg=violet ctermfg=darkmagenta +hi OL9 guifg=white ctermfg=gray + +" colors for tags +hi outlTags guifg=darkred ctermfg=darkred + +" color for body text +hi BT1 guifg=green ctermfg=darkgreen +hi BT2 guifg=green ctermfg=darkgreen +hi BT3 guifg=green ctermfg=darkgreen +hi BT4 guifg=green ctermfg=darkgreen +hi BT5 guifg=green ctermfg=darkgreen +hi BT6 guifg=green ctermfg=darkgreen +hi BT7 guifg=green ctermfg=darkgreen +hi BT8 guifg=green ctermfg=darkgreen +hi BT9 guifg=green ctermfg=darkgreen + +" color for pre-formatted text +hi PT1 guifg=blue ctermfg=darkcyan +hi PT2 guifg=blue ctermfg=darkcyan +hi PT3 guifg=blue ctermfg=darkcyan +hi PT4 guifg=blue ctermfg=darkcyan +hi PT5 guifg=blue ctermfg=darkcyan +hi PT6 guifg=blue ctermfg=darkcyan +hi PT7 guifg=blue ctermfg=darkcyan +hi PT8 guifg=blue ctermfg=darkcyan +hi PT9 guifg=blue ctermfg=darkcyan + +" color for tables +hi TA1 guifg=darkviolet ctermfg=darkcyan +hi TA2 guifg=darkviolet ctermfg=darkcyan +hi TA3 guifg=darkviolet ctermfg=darkcyan +hi TA4 guifg=darkviolet ctermfg=darkcyan +hi TA5 guifg=darkviolet ctermfg=darkcyan +hi TA6 guifg=darkviolet ctermfg=darkcyan +hi TA7 guifg=darkviolet ctermfg=darkcyan +hi TA8 guifg=darkviolet ctermfg=darkcyan +hi TA9 guifg=darkviolet ctermfg=darkcyan + +" color for user text (wrapping) +hi UT1 guifg=darkred ctermfg=darkcyan +hi UT2 guifg=darkred ctermfg=darkcyan +hi UT3 guifg=darkred ctermfg=darkcyan +hi UT4 guifg=darkred ctermfg=darkcyan +hi UT5 guifg=darkred ctermfg=darkcyan +hi UT6 guifg=darkred ctermfg=darkcyan +hi UT7 guifg=darkred ctermfg=darkcyan +hi UT8 guifg=darkred ctermfg=darkcyan +hi UT9 guifg=darkred ctermfg=darkcyan + +" color for user text (non-wrapping) +hi UB1 guifg=darkgray ctermfg=darkcyan +hi UB2 guifg=darkgray ctermfg=darkcyan +hi UB3 guifg=darkgray ctermfg=darkcyan +hi UB4 guifg=darkgray ctermfg=darkcyan +hi UB5 guifg=darkgray ctermfg=darkcyan +hi UB6 guifg=darkgray ctermfg=darkcyan +hi UB7 guifg=darkgray ctermfg=darkcyan +hi UB8 guifg=darkgray ctermfg=darkcyan +hi UB9 guifg=darkgray ctermfg=darkcyan + +" colors for folded sections +hi Folded guifg=darkcyan guibg=bg ctermfg=darkcyan ctermbg=black +hi FoldColumn guifg=darkcyan guibg=bg ctermfg=darkcyan ctermbg=black + +" colors for experimental spelling error highlighting +" this only works for spellfix.vim with will be cease to exist soon +hi spellErr gui=underline guifg=yellow cterm=underline ctermfg=darkyellow +hi BadWord gui=underline guifg=yellow cterm=underline ctermfg=darkyellow diff --git a/pack/acp/start/vimoutliner/colors/votl_light.vim b/pack/acp/start/vimoutliner/colors/votl_light.vim new file mode 100644 index 0000000..beef395 --- /dev/null +++ b/pack/acp/start/vimoutliner/colors/votl_light.vim @@ -0,0 +1,81 @@ +let g:colors_name="VO Light" +hi normal guifg=black guibg=white ctermfg=white ctermbg=black +hi StatusLine guifg=black guibg=white ctermfg=white ctermbg=black +hi StatusLineNC guifg=black guibg=white ctermfg=white ctermbg=black +hi VertSplit guifg=black guibg=white ctermfg=white ctermbg=black +hi OL1 guifg=black ctermfg=black +hi OL2 guifg=red ctermfg=red +hi OL3 guifg=blue ctermfg=blue +hi OL4 guifg=darkviolet ctermfg=magenta +hi OL5 guifg=black ctermfg=black +hi OL6 guifg=red ctermfg=red +hi OL7 guifg=blue ctermfg=blue +hi OL8 guifg=darkviolet ctermfg=magenta +hi OL9 guifg=black ctermfg=black + +" colors for tags +hi outlTags guifg=darkred ctermfg=darkred + +" color for body text +hi BT1 guifg=darkgreen ctermfg=green +hi BT2 guifg=darkgreen ctermfg=green +hi BT3 guifg=darkgreen ctermfg=green +hi BT4 guifg=darkgreen ctermfg=green +hi BT5 guifg=darkgreen ctermfg=green +hi BT6 guifg=darkgreen ctermfg=green +hi BT7 guifg=darkgreen ctermfg=green +hi BT8 guifg=darkgreen ctermfg=green +hi BT9 guifg=darkgreen ctermfg=green + +" color for pre-formatted text +hi PT1 guifg=darkblue ctermfg=cyan +hi PT2 guifg=darkblue ctermfg=cyan +hi PT3 guifg=darkblue ctermfg=cyan +hi PT4 guifg=darkblue ctermfg=cyan +hi PT5 guifg=darkblue ctermfg=cyan +hi PT6 guifg=darkblue ctermfg=cyan +hi PT7 guifg=darkblue ctermfg=cyan +hi PT8 guifg=darkblue ctermfg=cyan +hi PT9 guifg=darkblue ctermfg=cyan + +" color for tables +hi TA1 guifg=darkviolet ctermfg=cyan +hi TA2 guifg=darkviolet ctermfg=cyan +hi TA3 guifg=darkviolet ctermfg=cyan +hi TA4 guifg=darkviolet ctermfg=cyan +hi TA5 guifg=darkviolet ctermfg=cyan +hi TA6 guifg=darkviolet ctermfg=cyan +hi TA7 guifg=darkviolet ctermfg=cyan +hi TA8 guifg=darkviolet ctermfg=cyan +hi TA9 guifg=darkviolet ctermfg=cyan + +" color for user text (wrapping) +hi UT1 guifg=darkred ctermfg=cyan +hi UT2 guifg=darkred ctermfg=cyan +hi UT3 guifg=darkred ctermfg=cyan +hi UT4 guifg=darkred ctermfg=cyan +hi UT5 guifg=darkred ctermfg=cyan +hi UT6 guifg=darkred ctermfg=cyan +hi UT7 guifg=darkred ctermfg=cyan +hi UT8 guifg=darkred ctermfg=cyan +hi UT9 guifg=darkred ctermfg=cyan + +" color for user text (non-wrapping) +hi UB1 guifg=darkgray ctermfg=cyan +hi UB2 guifg=darkgray ctermfg=cyan +hi UB3 guifg=darkgray ctermfg=cyan +hi UB4 guifg=darkgray ctermfg=cyan +hi UB5 guifg=darkgray ctermfg=cyan +hi UB6 guifg=darkgray ctermfg=cyan +hi UB7 guifg=darkgray ctermfg=cyan +hi UB8 guifg=darkgray ctermfg=cyan +hi UB9 guifg=darkgray ctermfg=cyan + +" colors for folded sections +hi Folded guifg=darkcyan guibg=bg ctermfg=cyan ctermbg=white +hi FoldColumn guifg=darkcyan guibg=bg ctermfg=cyan ctermbg=white + +" colors for experimental spelling error highlighting +" this only works for spellfix.vim with will be cease to exist soon +hi spellErr gui=underline guifg=darkred cterm=underline ctermfg=darkred +hi BadWord gui=underline guifg=darkred cterm=underline ctermfg=darkred diff --git a/pack/acp/start/vimoutliner/colors/votl_test.vim b/pack/acp/start/vimoutliner/colors/votl_test.vim new file mode 100644 index 0000000..9866ace --- /dev/null +++ b/pack/acp/start/vimoutliner/colors/votl_test.vim @@ -0,0 +1,81 @@ +let g:colors_name="VO Light" +hi normal guifg=black guibg=white ctermfg=white ctermbg=black +hi StatusLine guifg=black guibg=white ctermfg=white ctermbg=black +hi StatusLineNC guifg=black guibg=white ctermfg=white ctermbg=black +hi VertSplit guifg=black guibg=white ctermfg=white ctermbg=black +hi OL1 guifg=black ctermfg=black +hi OL2 guifg=red ctermfg=red +hi OL3 guifg=blue ctermfg=blue +hi OL4 guifg=darkviolet ctermfg=magenta +hi OL5 guifg=black ctermfg=black +hi OL6 guifg=red ctermfg=red +hi OL7 guifg=blue ctermfg=blue +hi OL8 guifg=darkviolet ctermfg=magenta +hi OL9 guifg=black ctermfg=black + +" colors for tags +hi outlTags guifg=darkred ctermfg=darkred + +" color for body text +hi BT1 guifg=darkviolet ctermfg=magenta +hi BT2 guifg=black ctermfg=black +hi BT3 guifg=red ctermfg=red +hi BT4 guifg=blue ctermfg=blue +hi BT5 guifg=darkviolet ctermfg=magenta +hi BT6 guifg=black ctermfg=black +hi BT7 guifg=red ctermfg=red +hi BT8 guifg=blue ctermfg=blue +hi BT9 guifg=darkviolet ctermfg=magenta + +" color for pre-formatted text +hi PT1 guifg=darkblue ctermfg=cyan +hi PT2 guifg=darkblue ctermfg=cyan +hi PT3 guifg=darkblue ctermfg=cyan +hi PT4 guifg=darkblue ctermfg=cyan +hi PT5 guifg=darkblue ctermfg=cyan +hi PT6 guifg=darkblue ctermfg=cyan +hi PT7 guifg=darkblue ctermfg=cyan +hi PT8 guifg=darkblue ctermfg=cyan +hi PT9 guifg=darkblue ctermfg=cyan + +" color for tables +hi TA1 guifg=darkviolet ctermfg=cyan +hi TA2 guifg=darkviolet ctermfg=cyan +hi TA3 guifg=darkviolet ctermfg=cyan +hi TA4 guifg=darkviolet ctermfg=cyan +hi TA5 guifg=darkviolet ctermfg=cyan +hi TA6 guifg=darkviolet ctermfg=cyan +hi TA7 guifg=darkviolet ctermfg=cyan +hi TA8 guifg=darkviolet ctermfg=cyan +hi TA9 guifg=darkviolet ctermfg=cyan + +" color for user text (wrapping) +hi UT1 guifg=darkred ctermfg=cyan +hi UT2 guifg=darkred ctermfg=cyan +hi UT3 guifg=darkred ctermfg=cyan +hi UT4 guifg=darkred ctermfg=cyan +hi UT5 guifg=darkred ctermfg=cyan +hi UT6 guifg=darkred ctermfg=cyan +hi UT7 guifg=darkred ctermfg=cyan +hi UT8 guifg=darkred ctermfg=cyan +hi UT9 guifg=darkred ctermfg=cyan + +" color for user text (non-wrapping) +hi UB1 guifg=darkgray ctermfg=cyan +hi UB2 guifg=darkgray ctermfg=cyan +hi UB3 guifg=darkgray ctermfg=cyan +hi UB4 guifg=darkgray ctermfg=cyan +hi UB5 guifg=darkgray ctermfg=cyan +hi UB6 guifg=darkgray ctermfg=cyan +hi UB7 guifg=darkgray ctermfg=cyan +hi UB8 guifg=darkgray ctermfg=cyan +hi UB9 guifg=darkgray ctermfg=cyan + +" colors for folded sections +hi Folded guifg=darkcyan guibg=bg ctermfg=cyan ctermbg=white +hi FoldColumn guifg=darkcyan guibg=bg ctermfg=cyan ctermbg=white + +" colors for experimental spelling error highlighting +" this only works for spellfix.vim with will be cease to exist soon +hi spellErr gui=underline guifg=darkred cterm=underline ctermfg=darkred +hi BadWord gui=underline guifg=darkred cterm=underline ctermfg=darkred diff --git a/pack/acp/start/vimoutliner/doc/votl.txt b/pack/acp/start/vimoutliner/doc/votl.txt new file mode 100644 index 0000000..38671d7 --- /dev/null +++ b/pack/acp/start/vimoutliner/doc/votl.txt @@ -0,0 +1,1331 @@ +*votl_readme.txt* For Vim version 7.2 Last change: 2014-09-28 + + *vo* *votl* *vimoutliner* +VimOutliner 0.4.0 ~ + +VimOutliner is an outline processor designed with lighting fast authoring as +the main feature, it also has many of the same features as Grandview, More, +Thinktank, Ecco, etc. These features include tree expand/collapse, tree +promotion/demotion, level sensitive colors, interoutline linking, checkboxes +and body text. + + + License |votl-license| + Version |votl-version| + Installing and testing VimOutliner |votl-install| + Install via Pathogen |votl-pathogen-install| + Legacy Script Driven Method |votl-auto-install| + Updating |votl-updating| + Manual method |votl-manual-install| + Testing |votl-testing| + Debian |votl-debian| + Using VimOutliner on other file types |votl-other-files| + Troubleshooting |votl-troubleshooting| + VimOutliner philosophy |votl-philosophy| + Running VimOutliner |votl-running| + VimOutliner configuration file |vimoutlinerrc| + Comma comma commands |votl-command| + Basic VimOutliner activities |votl-activities| + Menu |votl-menu| + Vim Outliner objects |votl-objects| + Post Processors |votl-post-processors| + Advanced |votl-advanced| + Executable Lines |votl-executable-lines| + Plugins |votl-plugins| + Checkboxes |votl-checkbox| + Hoisting |votl-hoisting| + Clock |votl-clock| + Scripts |votl-scripts| + votl_maketags.pl |votl-maketags| + otl2html.py |otl2html| + Other information |votl-other-info| + + +============================================================================== +License *votl-license* + + +VimOutliner Copyright (C) 2001, 2003 by Steve Litt + Copyright (C) 2004, 2014 by Noel Henson +Licensed under the GNU General Public License (GPL), version 2 +Absolutely no warranty, see COPYING file for details. + + HTML: http://www.gnu.org/copyleft/gpl.html + Text: http://www.gnu.org/copyleft/gpl.txt + + +============================================================================== +Installing and Testing VimOutliner *votl-install* + + + Install via Pathogen |votl-pathogen-install| + Legacy Script Driven Method |votl-auto-install| + Updating |votl-updating| + Manual Method |votl-manual-install| + Testing |votl-testing| + + *votl-pathogen-install* +Install via Pathogen~ + +Preferred and most simple method of VimOutliner installation is using +Pathogen (developers of VimOutliner actually believe that Pathogen +(https://github.com/tpope/vim-pathogen), or Vundle, should be generally +the preferred way of installation of any vim plugin). + +Installation with working Pathogen should be just + + $ cd ~/.vim/bundle + # Or even better is to have whole ~/.vim/bundle as a separate repo + # and then plugins are added as submodules. + $ git clone git@github.com:vimoutliner/vimoutliner.git + +Restart vim and you should be good to go. If something does nott work, +please, let us know (either on the email list or file a ticket to the +GitHub issue tracker). + + *votl-auto-install* +Legacy Script Driven Method~ + +The automatic installation targets Unix-compatible platforms: > + +From tar archive + + $ tar xzvf vimoutliner-0.3.x.tar.gz + $ cd vimoutliner + $ sh install.sh + +From zip archive + + $ unzip vimoutliner-0.3.x.zip + $ cd vimoutliner-0.3.x + $ sh install.sh + +< +The install.sh script will ask you whether to install the VimOutliner files or +abort the process leaving everything unchanged. Assuming you confirmed the +installation, the script creates the necessary directory tree and copies the +files which provide the core functionality and documentation. + +With the second question you decide whether you want to install some brand new +add-ons, currently implementing hoisting and checkboxes. + + *votl-updating* +Updating~ + +Updating an existing installation might require some manual work. + +If you are already working with a previous VimOutliner release, there is a +slight chance that the current directory tree is different from your current +one. In this case, you will have to manually migrate your files to the new +locations. + +The installation script creates unique backups of files being replaced +with newer versions. So if you put some local customizations into +vimoutlinerrc in the directory where VimOutliner is run from (say +$HOME/.vim/vimoutliner/vimoutlinerrc), you'll probably have to merge the +backup with the new file by hand. Which is one good reason why it is +preferred to use for the custom configuration and extensions your own +copy of the |vimoutlinerrc| in some other location where the file is +sought for. + + *votl-manual-install* +Manual Method~ + +You can also copy the files from the unpacked distribution tar ball into their +destination folders by yourself. The following steps are a description of what +has to go where and assume some knowledge of your vim setup. + +If you encounter problems, please contact the mailing list for an immediate +solution and more complete future documentation. +https://groups.google.com/forum/#!forum/vimoutliner + +If you want to setup VimOutliner on a system running Microsoft Windows, the +directory $HOME denotes the base folder of the vim installation. If you're on +Unix based system, the location of $HOME is as usual. + +You need the following subtrees in your $HOME directory: > + + $HOME/.vim/ + doc/ + ftdetect/ + ftplugin/ + syntax/ + vimoutliner/ + plugins/ + scripts/ +< +The distribution tar ball unpacks into a directory vimoutliner with the +following contents: > + + vimoutliner/ + plugins/ (1) + scripts/ (1) + doc/ (1) + ftdetect/ (1) + ftplugin/ (1) + install.sh* + syntax/ (1) + syntax/ (1) + vimoutlinerrc (1) +< +(1) The content of these folders should be copied to their namesakes in the +$HOME/.vim folder + +Your $HOME/.vimrc file should contain the lines > + + filetype plugin indent on + syntax on +< +Finally, you need to integrate the online help provided with VimOutliner into +the vim help system. Start vim and execute the following command: > +> + :helptags $HOME/.vim/doc +< +At this point, VimOutliner should be functional. Type ":help vo" to get +started. You can also type ":help votl_cheatsheet" to a get a quick overview +of all the VimOutliner commands. + + *votl-testing* +Testing Base Functionality~ + +Open a new outline with the following: +> + rm $HOME/votl_test.otl + gvim $HOME/votl_test.otl or vim $HOME/votl_test.otl +< +Verify the following: +- Tabs indent the text +- Different indent levels are different colors +- Lines starting with a colon and space word-wrap + + Lines starting with colons are body text. They should word wrap and + should be a special color (typically green, but it can vary). Verify + that paragraphs of body text can be reformatted with the Vim gq + commands. + +Verify Interoutline Linking: + +Interoutline linking currently requires a working perl installation to +generate the necessary tag file. We are looking into porting this to vim's own +scripting language. + +Place the following two lines in $HOME/votl_test.otl: +> + _tag_newfile + $HOME/votl_newfile.otl +< +Note that in the preceding, the 2nd line should be indented from the first. + +To create VimOutliner's tag file $HOME/.vim/vimoutliner/votl_tags.tag, run +votl_maketags.pl, which resides in $HOME/.vimoutliner/scripts/: $ +$HOME/.vim/vimoutliner/scripts/votl_maketags.pl $HOME/votl_test.otl + +Try the following: +- In $HOME/votl_test.otl +- Cursor to the _tag_newfile marker +- Press CTRL-K + You should be brought to $HOME/votl_newfile.otl +- Press CTRL-N + You should be brought back to $HOME/votl_test.otl +Note: + CTRL-K is a VimOutliner synonym for CTRL-] + CTRL-N is a VimOutliner synonym for CTRL-T + +This might also be achieved more efficiently by using the UTL plugin for +linking to other files and text. Check out the plugin at: + +http://www.vim.org/scripts/script.php?script_id=293 + + *votl-debian* +Debian Installation~ + +Debian does include Vim Outliner as a package. However some Debian version +require this line to be added to your |vimrc| file: > + + syntax on +> + +============================================================================== +Using VimOutliner On Other File Types~ *votl-other-files* + +How to use VimOutliner on non .otl files~ + +Previous VimOutliner versions used the ol script to invoke VimOutliner. As of +VimOutliner 0.3.0, the ol script is no longer necessary nor provided. Instead, +VimOutliner is now a Vim plugin, so Vim does all the work. + +This makes VimOutliner much simpler to use in most cases, but Vim plugins are +file extension based, meaning that if you want to use VimOutliner on a file +extension other than .otl, you must declare that file extension in +$HOME/.vim/ftdetect/votl.vim. In this section we'll use the .emdl extension +(Easy Menu Definition Language) as an example. + +To enable VimOutliner work with .emdl files, do this: +> + vim $HOME/.vim/ftdetect/votl.vim +< +Right below the line reading: +> + au! BufRead,BufNewFile *.otl setfiletype votl +< +Insert the following line: +> + au! BufRead,BufNewFile *.emdl setfiletype votl +< +Save and exit +> + gvim $HOME/votl_test.emdl +< +You should get: +- level colors, +- body text (lines starting with colon) +- comma comma commands (try ,,2 and ,,1) + + +============================================================================== +Troubleshooting~ *votl-troubleshooting* + + +Q: I can't switch between colon based and space based body text. +A: See next question + +Q: My ,,b and ,,B don't do anything. How do I fix it? +A: Open vim like this: +> + vim $HOME/.vim/ftplugin/votl.vim +< + Search for use_space_colon + Make sure it is set to 0, not 1 + Rerun Vim, and ,,b and ,,B should work + +Q: I don't get VimOutliner features on files of extension .whatever. +A: Open vim like this: +> + vim $HOME/.vim/ftdetect/votl.vim +< + Right below the line reading: +> + au! BufRead,BufNewFile *.otl setfiletype votl +< + Insert the following line: +> + au! BufRead,BufNewFile *.whatever setfiletype votl +< + Save and exit. + + +============================================================================== +VimOutliner Philosophy~ *votl-philosophy* + + +Authoring Speed~ + +VimOutliner is an outline processor with many of the same features as +Grandview, More, Thinktank, Ecco, etc. Features include tree expand/collapse, +tree promotion/demotion, level sensitive colors, interoutline linking, and +body text. + +What sets VimOutliner apart from the rest is that it's been constructed from +the ground up for fast and easy authoring. Keystrokes are quick and easy, +especially for someone knowing the Vim editor. The mouse is completely +unnecessary (but is supported to the extent that Vim supports the mouse). Many +of the VimOutliner commands start with a double comma because that's very +quick to type. + +Many outliners are prettier than VimOutliner. Most other outliners are more +intuitive for the newbie not knowing Vim. Many outliners are more featureful +than VimOutliner (although VimOutliner gains features monthly and is already +very powerful). Some outliners are faster on lookup than VimOutliner. But as +far as we know, NO outliner is faster at getting information out of your mind +and into an outline than VimOutliner. + +VimOutliner will always give you lightning fast authoring. That's our basic, +underlying philosophy, and will never change, no matter what features are +added. + + +Vim Integration~ + +Earlier VimOutliner versions prided themselves on being stand alone +applications, self-contained in a single directory with a special script to +run everything. + +As of 0.3.0, VimOutliner is packaged as a Vim Plugin, eliminating the need for +the ol script, which many saw as clumsy. Given that all VimOutliner features +are produced by the Vim engine, it makes perfect sense to admit that +VimOutliner is an add-on to Vim. + +Therefore VimOutliner now prides itself in being a Vim plugin. With the +VimOutliner package installed, the Vim editor yields the VimOutliner feature +set for files whose extensions are listed as votl types in +$HOME/.vim/ftplugin/votl.vim. + + +============================================================================== +Running VimOutliner~ *votl-running* + + +Vim Knowledge~ + +You needn't be a Vim expert to use VimOutliner. If you know the basics -- +inserting and deleting line-wise and character-wise, moving between command and +insert modes, use of Visual Mode selections,and reformatting, you should be +well equipped to use VimOutliner. + +Run Vim or GVim and follow the instruction on :help |tutor| + +VimOutliner is a set of Vim scripts and configurations. Its features all come +from the Vim editor's engine. If you do not know Vim, you'll need to learn the +Vim basics before using VimOutliner. Start by taking the Vim tutorial. The +tutorial should take about 2 hours. + +VimOutliner is so fast, that if you often use outlining, you'll make up that +time within a week. + + *vimoutlinerrc* +VimOutliner configuration file~ + +Custom configuration (and small custom extensions) should be written to +the vimoutlinerrc file. It is a regular vimscript file and the first of +the files searched in the following locations will be used: + + * a file .vimoutlinerrc (notice the leading dot) in the users $HOME or + $HOME/.vimoutliner directory + * a file vimoutlinerrc (name without the leading dot) in the users + $HOME, $HOME/.vimoutliner, or $HOME/.vim directory + * a file vimoutlinerrc (again without the leading dot) in the folder + where the VimOutliner is run from (that could be again $HOME/.vim + directory with manual installation or for example + $HOME/.vim/bundle/vimoutliner when using pathogen) + +Many global variables can be also set in the normal vim manner in the +user’s $VIMRC file. See general vim documentation for more details for +individual variables. + + *votl-command* +Comma Comma Commands~ + +Traditionally (meaning in terms of the VimOutliner traditions ;)) all +VimOutliner were features accessed through keyboard commands starting +with two commas. The double comma followed by a character is incredibly +fast to type. However, with more widespread use of the VimOutliner some +developers felt that all idiosyncrasies should be eliminated and +VimOutliner should behave as a normal vim plugin. Therefore now we +don’t redefine this command leader (as it is called in the Vim lingo) +and unless the user redefines it on her own (in |vimoutlinerrc|) it +defaults to backslash. If you configure VimOutliner to use different key +combination, you have to mentally replace it everywhere in this +documentation. + +If you are friend of the ancient regime, then just uncomment the line in +|vimoutlinerrc| (see more about the locations where you should put it): + + "let maplocalleader = ',,' " uncomment for compatibility with + " previous versions of VO + +We expect to create more comma comma commands, so try not to create your own, +as they may clash with later comma comma commands. If you have an +exceptionally handy command, please report it to the VimOutliner list. Perhaps +others could benefit from it. + + Command List Description ~ + ,,D all VimOutliner reserved command + ,,H all reserved for manual de-hoisting (add-on) + ,,h all reserved for hoisting (add-on) + ,,1 all set foldlevel=0 + ,,2 all set foldlevel=1 + ,,3 all set foldlevel=2 + ,,4 all set foldlevel=3 + ,,5 all set foldlevel=4 + ,,6 all set foldlevel=5 + ,,7 all set foldlevel=6 + ,,8 all set foldlevel=7 + ,,9 all set foldlevel=8 + ,,0 all set foldlevel=99999 + ,,- all Draw dashed line + ,,f normal Directory listing of the current directory + ,,s normal Sort sub-tree under cursor ascending + ,,S normal Sort sub-tree under cursor descending + ,,t normal Append timestamp (HH:MM:SS) to heading + ,,T normal Pre-pend timestamp (HH:MM:SS) to heading + ,,T normal Pre-pend timestamp (HH:MM:SS) to heading + ,,t insert Insert timestamp (HH:MM:SS) at cursor + ,,d normal Append datestamp (YYYY-MM-DD) to heading + ,,d insert Insert datestamp (YYYY-MM-DD) at cursor + ,,D normal Pre-pend datestamp (YYYY-MM-DD) to heading + ,,B normal Make body text start with a space + ,,b normal Make body text start with a colon and space + ,,w insert Save changes and return to insert mode + ,,e normal Execute the executable tag line under cursor + + +Other VimOutliner Commands~ + +Naturally, almost all Vim commands work in VimOutliner. Additionally, +VimOutliner adds a few extra commands besides the comma comma commands +discussed previously. + +Command list: + CTRL-K Follow tag (Synonym for CTRL-]) + CTRL-N Return from tag (Synonym for CTRL-T) + Q Reformat (Synonym for gq) + + +To get a quick overview of all VimOutliner commands type ":help votl_cheatsheet" in vim. + + *votl-activities* +Basic VimOutliner activities~ + +How do I collapse a tree within command mode? + zc + (note: a full list of folding commands |fold-commands|) + +How do I expand a tree within command mode? + To expand one level: + zo + To expand all the way down + zO + +How do I demote a headline? + In command mode, >> + In insert mode at start of the line, press the Tab key + In insert mode within the headline, CTRL-T + +How do I promote a headline? + In command mode, << + In insert mode at start of the line, press the Backspace key + In insert mode within the headline, CTRL-D + +How do I promote or demote several consecutive headlines? + Highlight the lines with the V command + Press < to promote or > to demote. You can precede + the < or > with a count to promote or demote several levels + +How do I promote or demote an entire tree? + Collapse the tree + Use << or >> as appropriate + +How do I collapse an entire outline? + ,,1 + +How do I maximally expand an entire outline? + ,,0 + +How do I expand an outline down to the third level? + ,,3 + +How do I move a tree? + Use Vim's visual cut and paste + +How do I create body text? + Open a blank line below a headline + Start the line with a colon followed by a space + Continue to type. Your text will wrap + +How do I reformat body text? + Highlight (Shift+V) the body text to be reformatted + Use the gq command to reformat + +How do I reformat one paragraph of body text? + The safest way is highlighting. + DANGER! Other methods can reformat genuine headlines. + +How do I switch between colon based and space based body text? + ,,b for colon based, ,,B for space based + +What if ,,b and ,,B don't work + Change variable use_space_colon from 1 to 0 + in $HOME/.vim/ftplugin/votl.vim + +How do I perform a word count? + Use the command :w !wc + The space before the exclamation point is a MUST. + + *votl-menu* +Menu~ + +There is a simple menu included in Vim Outliner when running in GUI mode. +Named 'VO', you can usually find it right next to the 'Help' menu. There are +commands to change the fold level and select alternate color schemes. There is +also entries for common tools. + +The last tool item calls a shell script, 'myotl2html.sh'. This script should +be provided by the user and is not included in VO releases. A sample +myotl2html.sh script might look like this: +> + #!/bin/bash + otl2html.py -S pjtstat.css $1 > $HOME/public_html/$1.html +< +If you have several different types of reports you create regularly, you can +create your own menu entries. Just add lines like these to your +|vimoutlinerrc| file: > +> + amenu &VO.&Reports.&Big\ Project :!otl2html.py -S big.css % > %.html + amenu &VO.&Reports.&Hot\ List :!otl2html.py -S todo.css % > %.html + amenu &VO.&Reports.&Weekly :!otl2html.py -S weekly.css % > %.html +< +I'm sure you get the idea. + + *votl-objects* +Vim Outliner Objects~ + +There are several object/line types that VO supports. The most common on +simple headings and body text. Simple headings are tab-indented line that +start with any non-whitespace character except: : ; | < >. These characters +specify other objects. Here is a list of each of the non-heading types: + + Start Description~ + : body text (wrapping) + ; Pre-formatted body text (non-wrapping) + | table + > user-defined, text block (wrapping) + < user-defined, Pre-formatted text block (non-wrapping) + +The body text marker, :, is used to specify lines that are automatically +wrapped and reformatted. VO and post-processors are free to wrap and reformat +this text as well as use proportionally- spaced fonts. A post-processor will +probably change the appearance of what you have written. If you are writing a +book or other document, most of the information you enter will be body text. + +Here is an example: +> + Kirby the Wonder Dog + : Kirby is nine years old. He understand about 70-100 + : English words. Kirby also understands 11 different hand + : signals. He is affectionate, playful and attentive. + : + : His breeding is unknown. He appears to be a mix between + : a German shepherd and a collie. +< +When folded, body text looks something like this: +> + Kirby the Wonder Dog + [TEXT] -------------------------------- (6 lines) +< +The Pre-formatted text marker, ;, is used to mark text that should not be +reformatted nor wrapped by VO or any post-processor. A post- processor would +use a fixed-space font, like courier, to render these lines. A post-processor +will probably not change the appearance of what you have written. This is +useful for making text picture, program code or other format-dependent text. + +Here is an example: +> + Output waveform + ; _______ ______ + ; _____/ \______________/ + ; |-10us--|----35us------| +< +When folded, Pre-formatted body text looks something like this: +> + Output waveform + [TEXT BLOCK] -------------------------- (6 lines) +< +The table marker, |, is used to create tables. This is an excellent way to +show tabular data. The marker is used as if it were are real vertical line. A +|| (double-|) is optionally used to mark a table heading line. This is useful +for post-processors. + +Here is an example: +> + Pets + || Name | Age | Animal | Inside/Outside | + | Kirby | 9 | dog | both | + | Hoover | 1 | dog | both | + | Sophia | 9 | cat | inside | +< +There is no automatic alignment of columns yet. It must be done manually. The +post-processor, otl2thml.py, does have alignment functions. See its +documentation for more information. + +When folded, a table looks something like this: +> + Pets + [TABLE] ------------------------------- (4 lines) +< +User-defined text is similar to body text but more flexible and it's use is +not pre-defined by Vim Outliner. The basic, user-defined text block marker, >, +behaves just like body text. + +For example: +> + Kirby the Wonder Dog + > Kirby is nine years old. He understand about 70-100 + > English words. Kirby also understands 11 different hand + > signals. He is affectionate, playful and attentive. + > + > His breeding is unknown. He appears to be a mix between + > a German shepherd and a collie. +< +When folded, body text looks something like this: +> + Kirby the Wonder Dog + [USER] -------------------------------- (6 lines) +< +But unlike body text, user-defined text can be expanded. You could have +user-defined text types. If you were writing a book, in addition to body text +for paragraphs you might need special paragraphs for tips and warnings. +User-defined text blocks can accomplish this: +> + >Tips + > Don't forget to back up your computer daily. You don't + > need to back up the entire computer. You just need to + > backup up the files that have changed. + >Warning + >Never store you backup floppy disks on the side of you + >file cabinets by adhering them with magnets. +< +A post processor will know how to remove the style tags (Tips and Warning) and +you want the text to be formatted. + +When folded, the above would appear as: +> + [USER Tips] --------------------------- (4 lines) + [USER Warning]------------------------- (3 lines) +< +The user-defined, pre-formatted text block marker, <, behaves just like +pre-formatted text. But like >, it leaves the functional definition up to the +user. A simple user-defined, pre-formatted text block could be: +> + Tux + < _.._ + < .-' `-. + < : ; + < ; ,_ _, ; + < : \{" "}/ : + < ,'.'"=..=''.'. + < ; / \ / \ ; + < .' ; '.__.' ; '. + < .-' .' '. '-. + < .' ; ; '. + < / / \ \ + < ; ; ; ; + < ; `-._ _.-' ; + < ; ""--. .--"" ; + < '. _ ; ; _ .' + < {""..' '._.-. .-._.' '..""} + < \ ; ; / + < : : : : + < : :.__.: : + < \ /"-..-"\ / fsc + < '-.__.' '.__.-' +< +When folded it would be: +> + Tux + [USER BLOCK] -------------------------- (6 lines) +< +Like user-defined text, these blocks can be given user-defined styles. For +example: +> + + [USER BLOCK ASCIIart] ----------------- (22 lines) + [USER BLOCK Code] --------------------- (17 lines) +< + + *votl-post-processors* +VimOutliner Post-Processors~ + +There are already several post processors for Vim Outliner. Some are general +purpose in nature and others perform specific conversions. There are several of +the tested scripts now included in the $HOME/.vim/vimoutliner/scripts folder. +See also the scripts section. |votl-scripts| + + +============================================================================== +Advanced VimOutliner *votl-advanced* + + *votl-executable-lines* +Executable Lines~ + +Executable lines enable you to launch any command from a specially constructed +headline within VimOutliner. The line must be constructed like this: +> + Description _exe_ command +< +Here's an example to pull up Troubleshooters.Com: +> + Troubleshooters.Com _exe_ mozilla http://www.troubleshooters.com +< +Executable lines offer the huge benefit of a single-source knowledge tree, +where all your knowledge, no matter what its format, exists within a single +tree of outlines connected with inter-outline links and executable lines. + +A more efficient and feature rich way to achieve this might be to use the UTL +plugin for vim. See the scripts section at http://www.vim.org + + +============================================================================== +Plugins *votl-plugins* + + +The VimOutliner distribution currently includes plugins for easy handling +of checkboxes, hoisting (see below), smart paste, clocking, math and format. + +The checkboxes tags and smart paste plugins are enabled by default. The +hoisting, clocking, math and format plugins are disabled by default. To +enable these plugins look for the easy instructions for this in your +|vimoutlinerrc| file. + +More information below and in the plugin files in the directory where +the VimOutliner is run from (either $HOME/.vim/vimoutliner/plugin for +manual installation or $HOME/.vim/bundle/vimoutliner/plugin when using +pathogen). + + *votl-checkbox* +Checkboxes~ + +Checkboxes enable VimOutliner to understand tasks and calculate the current +status of todo-lists etc. Three special notations are used: +> + [_] an unchecked item or incomplete task + [X] a checked item or complete task + % a placeholder for percentage of completion +< +Several ,,-commands make up the user interface: +> + ,,cb Insert a check box on the current line or each line of the currently + selected range (including lines in selected but closed folds). This + command is currently not aware of body text. Automatic recalculation + of is performed for the entire root-parent branch that contains the + updated child. (see ,,cz) + ,,cx Toggle check box state (percentage aware) + ,,cd Delete check boxes + ,,c% Create a check box with percentage placeholder except on childless + parents + ,,cp Create a check box with percentage placeholder on all headings + ,,cz Compute completion for the tree below the current heading. +< +How do I use it? + +Start with a simple example. Let's start planning a small party, say a barbecue. + +1. Make the initial outline. +> + Barbecue + Guests + Bill and Barb + Larry and Louise + Marty and Mary + Chris and Christine + David and Darla + Noel and Susan + Food + Chicken + Ribs + Corn on the cob + Salad + Desert + Beverages + Soda + Iced Tea + Beer + Party Favors + Squirt guns + Hats + Name tags + Materials + Paper Plates + Napkins + Trash Containers +< + +2. Add the check boxes. + +This can be done by visually selecting them and typing ,,cb. When done, you +should see this: +> + [_] Barbecue + [_] Guests + [_] Bill and Barb + [_] Larry and Louise + [_] Marty and Mary + [_] Chris and Christine + [_] David and Darla + [_] Noel and Susan + [_] Food + [_] Chicken + [_] Ribs + [_] Corn on the cob + [_] Salad + [_] Desert + [_] Beverages + [_] Soda + [_] Iced Tea + [_] Beer + [_] Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] Materials + [_] Paper Plates + [_] Napkins + [_] Trash Containers +< + +3. Now check off what's done. + +Checking off what is complete is easy with the +,,cx command. Just place the cursor on a heading and ,,cx it. Now you can see +what's done as long as the outline is fully expanded. +> + [_] Barbecue + [_] Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [X] Chris and Christine + [X] David and Darla + [X] Noel and Susan + [_] Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] Salad + [X] Desert + [_] Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers +< + +4. Now summarize what's done. + +You can summarize what is done with the ,,cz command. Place the cursor on the +'Barbecue' heading and ,,cz it. The command will recursively process the +outline and update the check boxes of the parent headlines. You should see: +(Note: the only change is on the 'Guests' heading. It changed because all of +its children are complete.) +> + [_] Barbecue + [X] Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [X] Chris and Christine + [X] David and Darla + [X] Noel and Susan + [_] Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] Salad + [X] Desert + [_] Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers +< + +5. Add percentages for a better view. + +You can get a much better view of what's going on, especially with collapsed +headings, if you add percentages. Place a % on each heading that has children +like this: +> + [_] % Barbecue + [X] % Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [X] Chris and Christine + [X] David and Darla + [X] Noel and Susan + [_] % Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] Salad + [X] Desert + [_] % Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] % Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] % Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers +< + +6. Now compute the percentage of completion. + +After adding the % symbols, place the cursor on the 'Barbecue' heading and +execute ,,cz as before. Keep in mind that the recursive percentages are +weighted. You should see: +> + [_] 58% Barbecue + [X] 100% Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [X] Chris and Christine + [X] David and Darla + [X] Noel and Susan + [_] 60% Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] Salad + [X] Desert + [_] 66% Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] 0% Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] 66% Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers +< + +7. Complete a few more just for fun. + +Mark Salad and Soda and you should see the outline below. Try playing around +with zc and zo to see the effects of opening and closing folds. Even if you +place the cursor on 'Barbecue' and zo it, you still have a good understanding +of how complete the project is. +> + [_] 69% Barbecue + [X] 100% Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [X] Chris and Christine + [X] David and Darla + [X] Noel and Susan + [_] 80% Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [X] Salad + [X] Desert + [X] 100% Beverages + [X] Soda + [X] Iced Tea + [X] Beer + [_] 0% Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] 66% Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers +< + *votl-hoisting* +Hoisting~ + +Hoisting is a way to focus on the offspring of the currently selected outline +item. The sub items will be presented as top level items in the automatically +extracted hoist-file located in the same directory as the main outline file. +You cannot hoist parts of an already hoisted file again. + +To enable this plugin uncomment the following line in |vimoutlinerrc|: +> + "let g:vo_modules_load .= ':newhoist' +< +Once it is enabled, you hoist the subtopics of the currently selected +item with + + ,,h Hoist the subtopics into a temporary file + +The changes are merged back into the original file by closing the temporary +hoist file with + + :q :wq :x ZZ + +If something went wrong, you can perform a manual de-hoisting with the +following procedure: + +Open the main file in VimOutliner Search for the line containing the __hoist +tag On this line, do + + ,,H Manual de-hoisting + + *votl-clock* +Clock~ + +The clock plugin is a little imitation of a nice feature from emacs org mode. +The clockpugin allows to track times and summarize them up in the parent +heading. + +To enable this plugin uncomment the following line in |vimoutlinerrc|: +> + "let g:vo_modules_load .= ':clock' +< +To start clocking you need to write a heading containing times in square +brackets like shown below. After the closing bracket -> indicates the place +where the calculated time is written. The arrow can be followed by a char to +indicate to unit in which the time is displayed. Use 's' for seconds, 'm' for +minutes, 'h' for hours and 'd' for days. If no unit is given hours are used. +> + Year 2011 -> d + January -> + Monday, 3th [08:30:00 -- 17:45:00] -> m + Tuesday, 3th [08:50:25 -- 18:00:02] -> s +< + +To summarize the times up within the outline headings ending with -> {char} +use + + ,,cu Clock update with the cursor somewhere in the hierarchy. + +After that the outline should look like this: +> + Year 2011 -> 0.77 d + January -> 18.41 h + Monday, 3th [08:30:00 -- 17:45:00] -> 555.00 m + Tuesday, 3th [08:50:25 -- 18:00:02] -> 32977 s +< +Every time the times are changed or the units where changed use ,,cu to update +all times within the hierarchy. + +Mappings for fast clocking: + + ,,cs Clock start. Date and current time as start and end time are + written at cursor position. Works in normal mode and insert mode. +> + Year 2011 -> 0.77 d + January -> 18.41 h + Monday, 3th [08:30:00 -- 17:45:00] -> 555.00 m + Tuesday, 3th [08:50:25 -- 18:00:02] -> 32977 s + 2011-10-11 [01:32:11 -- 01:32:11] -> +> +To set a new end time, place the cursor at the desired line and use following +mapping: + + ,,cS Clock stop. Set the end time to current time. This works also in + normal mode and insert mode. + +> + Year 2011 -> 0.77 d + January -> 18.41 h + Monday, 3th [08:30:00 -- 17:45:00] -> 555.00 m + Tuesday, 3th [08:50:25 -- 18:00:02] -> 32977 s + 2011-10-11 [01:32:11 -- 01:42:19] -> 0.17 h +> +At the moment there are no user defined time formats supported. And it's not +possible to clock times over the midnight like [22:25:00 -- 01:00:00], but +it's usable for the most important cases. + + +============================================================================== +Scripts *votl-scripts* + + +The VimOutliner distribution currently includes several useful external +scripts to support interoutline links, HTML export and more. All scripts are +included in your $HOME/.vim/vimoutliner/scripts folder. For more information +on these scripts see usage section in the scripts. You can also find several +of these scripts on this web site with links to their specific web site: +https://sites.google.com/site/vimoutlinerinfo/scripts-for-vimoutliner + + +Information on some of the scripts + +votl_maketags.pl *votl-maketags* + +A basic description of how to use this Perl script is given in section +|votl-testing|, subsection "Verify interoutline linking". + +otl2html.py *otl2html* + +This Python script transforms an outline into an HTML file. Use $ otl2html.py +--help to get detailed information. + +This script does not adhere to the VimOutliner naming convention with the +'votl_' prefix because it is not necessary for any VimOutliner functionality. +It is provided both as a useful tool for creating HTML pages and HTML slides +from outlines and as a working demonstration of how to convert .otl files to +other formats. + + +============================================================================== +Other Information *votl-other-info* + + +The VimOutliner Project~ + +- How do I add my own features? +Two ways -- by changing VimOutliner source code, or by inserting your own code +in |vimoutlinerrc|, which runs at the end of the VimOutliner startup +scripts. You might have to merge your personal vimoutlinerrc with future +versions to take advantage of new features. + +- How is VimOutliner licensed? +VimOutliner is licensed under the GNU General Public License. + +- How do I contribute to VimOutliner +Step 1 is to subscribe to our mailing list. Join up at +https://groups.google.com/forum/#!forum/vimoutliner. +Lurk for a few days or so to get the feel, then submit your idea/suggestion. +A lively discussion will ensue, after which your idea, probably in some modified +form, will be considered. The more of the actual work you have done, the more +likely your feature will go in the distribution in a timely manner. + + +- What's with the VimOutliner file names? +All VimOutliner files must begin with votl_ unless Vim itself requires them to +have a different name. A few older files from previous versions break this +rule, but over time these will be changed to our naming convention. + +In the old days, with the "self contained" philosophy, there was no naming +convention, because VimOutliner files were segregated into their own tree. +With the coming of the "vim plugin" philosophy, there's a need to identify +VimOutliner files for purposes of modification, upgrade and de-installation. +Hence our naming convention. + +- What if my feature doesn't make it into the VimOutliner distribution? +You can offer it on your own web site, or very possibly on +to the forthcoming new VimOutliner home page VimOutliner ships with its +core features, but many additional functionalities, especially those that +operate from Perl scripts (or bash or python) are available outside the +distro. For instance, right now there's an Executable Line feature that turns +VimOutliner into a true single tree information reservoir. The Executable Line +feature is available extra-distro on the VimOutliner home page. See also the +scripts included in the $HOME/.vim/vimoutliner/scripts folder. + + +Anticipated improvements in later versions~ + +Command-invoking headlines + Already prototyped + Probably coming next version + Allows you to press a key and get an html command in a browser + Enables a true single tree knowledge collection + Enables use of VimOutliner as a shell + +Groupware + Not yet well defined + Enables collaborative work on an outline + A pipe dream, but VimOutliner itself was once a pipe dream + +Easy mode + Let's Windows users operate VO like a common insert-only editor. This will + remove a great deal of VO's keyboarder- friendly features. But then, + they're Windows users: let them use the mouse. + +Headline to headline links + Not yet sanctioned, might never be implemented If implemented, this would + presumably create links not just between outlines, but between headlines, + either in the same outline or in a different one. This would be a start on + "neural networking". + +Headline numbering + Under feasibility investigation + Supported by external scripts + +Toolbar in gvim + Under feasibility investigation + + +Further information on outlines, outline processing and outliners~ + +http://www.vim.org/scripts/script.php?script_id=3515 +vim.org script site + +http://freecode.com/projects/vimoutliner +Main distribution website + +https://github.com/vimoutliner/vimoutliner +git repository + +http://www.troubleshooters.com/projects/alt-vimoutliner-litt/ +Preliminary main web site with links to other sites + +http://www.troubleshooters.com/tpromag/199911/199911.htm +Outlining discussion, not product specific + +http://www.troubleshooters.com/linux/olvim.htm +Discussion on how to use Vim for outlining + +http://www.troubleshooters.com/projects/vimoutliner.htm +Former Web page for the VimOutliner distro + +http://www.outliners.com +Discussion of (proprietary) outliners from days gone by. +Downloads for ancient versions of such outliners. +Unfortunately, all are DOS, Windows and Mac. + +http://members.ozemail.com.au/~caveman/Creative/Software/Inspiration/index.html +Discussion of (proprietary,Mac) Inspiration software +This page discusses many methods of thought/computer interaction: + Visual Outlining + Textual Outlining + Idea mapping + Mind Mapping + Brainstorming with Rapid Fire Entry + Concept Mapping + Story boarding + Diagrams (using rich symbol library) + +http://members.ozemail.com.au/~caveman/Creative/index.html +Not about outlines, but instead about how to use your brain. +The whole purpose of outlines is to use your brain. +New ways of using your brain produce new ways to use outlines. + +For the VimOutliner version information and history, see the CHANGELOG. + diff --git a/pack/acp/start/vimoutliner/doc/votl_cheatsheet.txt b/pack/acp/start/vimoutliner/doc/votl_cheatsheet.txt new file mode 100644 index 0000000..d9f877d --- /dev/null +++ b/pack/acp/start/vimoutliner/doc/votl_cheatsheet.txt @@ -0,0 +1,85 @@ + *votl_cheatsheet.txt* Last change: 2013-04-06 + +VIMOUTLINER CHEAT SHEET~ + +This overview has Vimoutliner specific commands for the available operations. +Remember that all Vim commands can be performed in Vimoutliner files. This is +especially useful for copying, pasting, moving around and similar commands. + +For more extensive descriptions of command uses in Vimoutliner do ':h vo-command'. |vo-command| + +List format explained: [command] [mode] [description] + + + +CHECKBOXES~ + +,,cb normal Insert a check box on the current line/range +,,cx normal Toggle check box state (percentage aware) +,,cd normal Delete check boxes +,,c% normal Create a check box with percentage placeholder +,,cp normal Create a check box with percentage placeholder on all +headings +,,cz normal Compute completion for the tree below the current +heading. + + +EXECUTABLE LINES~ + +,,e normal Execute the executable tag line under cursor + + +FOLDING~ + +,,1 all set foldlevel=0 +,,2 all set foldlevel=1 +,,3 all set foldlevel=2 +,,4 all set foldlevel=3 +,,5 all set foldlevel=4 +,,6 all set foldlevel=5 +,,7 all set foldlevel=6 +,,8 all set foldlevel=7 +,,9 all set foldlevel=8 +,,0 all set foldlevel=99999 + + +FORMATTING~ + +,,- all Draw dashed line +,,s normal Sort sub-tree under cursor ascending +,,S normal Sort sub-tree under cursor descending +,,B normal Make body text start with a space +,,b normal Make body text start with a colon and space +>> normal Demote headline +<< normal Promote headline + insert Demote headline + insert Promote headline +Q normal Reformat (Synonym for gq) + + +OTHER~ + +,,f normal Directory listing of the current directory +,,w insert Save changes and return to insert mode +,,D all VimOutliner reserved command + + +TAGGING/INTEROUTLINE~ + + normal Follow tag/interoutline (Synonym for Ctrl+]) + normal Return from tag (Synonym for Ctrl+T) + + +TIME AND DATE~ + +,,t normal Append timestamp (HH:MM:SS) to heading +,,T normal Prepend timestamp (HH:MM:SS) to heading +,,t insert Insert timestamp (HH:MM:SS) at cursor +,,d normal Append datestamp (YYYY-MM-DD) to heading +,,d insert Insert datestamp (YYYY-MM-DD) at cursor +,,D normal Prepend datestamp (YYYY-MM-DD) to heading + + + vim:set filetype=help textwidth=78: + + diff --git a/pack/acp/start/vimoutliner/ftdetect/votl.vim b/pack/acp/start/vimoutliner/ftdetect/votl.vim new file mode 100644 index 0000000..2897f50 --- /dev/null +++ b/pack/acp/start/vimoutliner/ftdetect/votl.vim @@ -0,0 +1,26 @@ +"# ####################################################################### +"# filetype.vim: filetype loader +"# version 0.4.0 +"# Copyright (C) 2001,2003 by Steve Litt (slitt@troubleshooters.com) +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"# +"# You should have received a copy of the GNU General Public License +"# along with this program; if not, see . +"# +"# Steve Litt, slitt@troubleshooters.com, http://www.troubleshooters.com +"# ####################################################################### + +augroup filetypedetect + au! BufRead,BufNewFile *.otl setfiletype votl + au! BufRead,BufNewFile *.oln setfiletype xoutliner +augroup END + diff --git a/pack/acp/start/vimoutliner/ftplugin/votl.vim b/pack/acp/start/vimoutliner/ftplugin/votl.vim new file mode 100644 index 0000000..84b69ad --- /dev/null +++ b/pack/acp/start/vimoutliner/ftplugin/votl.vim @@ -0,0 +1,679 @@ +"######################################################################### +"# ftplugin/votl.vim: VimOutliner functions, commands and settings +"# version 0.4.0 +"# Copyright (C) 2001,2003 by Steve Litt (slitt@troubleshooters.com) +"# Copyright (C) 2004,2014 by Noel Henson (noelwhenson@gmail.com) +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"# +"# You should have received a copy of the GNU General Public License +"# along with this program; if not, see . +"# +"# Steve Litt, slitt@troubleshooters.com, http://www.troubleshooters.com +"######################################################################### + +" Load the plugin {{{1 +" Prevent the plugin from being loaded twice +"if exists("b:did_ftplugin") +" finish +"endif +"let b:did_ftplugin = 1 +let b:current_syntax = "outliner" + +" Default Preferences {{{1 + +let use_space_colon=0 + +" End User Preferences + +" VimOutliner Standard Settings {{{1 +setlocal autoindent +"setlocal backspace=2 +setlocal wrapmargin=5 +setlocal wrap +setlocal tw=78 +setlocal noexpandtab +setlocal tabstop=4 " tabstop and shiftwidth must match +setlocal shiftwidth=4 " values from 2 to 8 work well +"setlocal nosmarttab +"setlocal softtabstop=0 +setlocal foldlevel=20 +setlocal foldcolumn=1 " turns on "+" at the beginning of close folds +setlocal foldmethod=expr +setlocal foldexpr=MyFoldLevel(v:lnum) +setlocal indentexpr= +setlocal nocindent +setlocal iskeyword=@,39,45,48-57,_,129-255 + +" Vim Outliner Functions {{{1 + +if !exists("loaded_vimoutliner_functions") +let loaded_vimoutliner_functions=1 + +" Sorting {{{2 +" IsParent(line) {{{3 +" Return 1 if this line is a parent +function! IsParent(line) + return (Ind(a:line)+1) == Ind(a:line+1) +endfunction +"}}}3 +" FindParent(line) {{{3 +" Return line if parent, parent line if not +function! FindParent(line) + if IsParent(a:line) + return a:line + else + let l:parentindent = Ind(a:line)-1 + let l:searchline = a:line + while (Ind(l:searchline) != l:parentindent) && (l:searchline > 0) + let l:searchline = l:searchline-1 + endwhile + return l:searchline + endif +endfunction +"}}}3 +" FindLastChild(line) {{{3 +" Return the line number of the last decendent of parent line +function! FindLastChild(line) + let l:parentindent = Ind(a:line) + let l:searchline = a:line+1 + while Ind(l:searchline) > l:parentindent + let l:searchline = l:searchline+1 + endwhile + return l:searchline-1 +endfunction +"}}}3 +" MoveDown() {{{3 +" Move a heading down by one +" Used for sorts and reordering of headings +function! MoveDown() + call cursor(line("."),0) + del x + put x +endfunction +"}}}3 +" DelHead() {{{3 +" Delete a heading +" Used for sorts and reordering of headings +function! DelHead(line) + let l:fstart = foldclosed(a:line) + if l:fstart == -1 + let l:execstr = a:line . "del x" + else + let l:fend = foldclosedend(a:line) + let l:execstr = l:fstart . "," . l:fend . "del x" + endif + exec l:execstr +endfunction +" PutHead() {{{3 +" Put a heading +" Used for sorts and reordering of headings +function! PutHead(line) + let l:fstart = foldclosed(a:line) + if l:fstart == -1 + let l:execstr = a:line . "put x" + exec l:execstr + else + let l:fend = foldclosedend(a:line) + let l:execstr = l:fend . "put x" + exec l:execstr + endif +endfunction +"}}}3 +" NextHead(line) {{{3 +" Return line of next heading +" Used for sorts and reordering of headings +function! NextHead(line) + let l:fend = foldclosedend(a:line) + if l:fend == -1 + return a:line+1 + else + return l:fend+1 + endif +endfunction +"}}}3 +" CompHead(line) {{{3 +" Compare this heading and the next +" Return 1: next is greater, 0 next is same, -1 next is less +function! CompHead(line) + let nexthead = NextHead(a:line) + let l:thisline=getline(a:line) + let l:nextline=getline(nexthead) + if indent(a:line) != indent(nexthead) + return 0 + elseif l:thisline <# l:nextline + return 1 + elseif l:thisline ># l:nextline + return -1 + else + return 0 + endif +endfunction + +"}}}3 +" Sort1Line(line) {{{3 +" Compare this heading and the next and swap if out of order +" Dir is 0 for forward, 1 for reverse +" Return a 1 if a change was made +function! Sort1Line(line,dir) + if (CompHead(a:line) == -1) && (a:dir == 0) + call DelHead(a:line) + call PutHead(a:line) + return 1 + elseif (CompHead(a:line) == 1) && (a:dir == 1) + call DelHead(a:line) + call PutHead(a:line) + return 1 + else + return 0 + endif +endfunction +"}}}3 +" Sort1Pass(start,end,dir) {{{3 +" Compare this heading and the next and swap if out of order +" Dir is 0 for forward, 1 for reverse +" Return a 0 if no change was made, other wise return the change count +function! Sort1Pass(fstart,fend,dir) + let l:i = a:fstart + let l:changed = 0 + while l:i < a:fend + let l:changed = l:changed + Sort1Line(l:i,a:dir) + let l:i = NextHead(l:i) + endwhile + return l:changed +endfunction +"}}}3 +" Sort(start,end,dir) {{{3 +" Sort this range of headings +" dir: 0 = ascending, 1 = decending +function! SortRange(fstart,fend,dir) + let l:changed = 1 + while l:changed != 0 + let l:changed = Sort1Pass(a:fstart,a:fend,a:dir) + endwhile +endfunction +"}}}3 +" SortChildren(dir) {{{3 +" Sort the children of a parent +" dir: 0 = ascending, 1 = descending +function! SortChildren(dir) + let l:oldcursor = line(".") + let l:fstart = FindParent(line(".")) + let l:fend = FindLastChild(l:fstart) + let l:fstart = l:fstart + if l:fend <= l:fstart + 1 + return + endif + call append(line("$"),"Temporary last line for sorting") + mkview + let l:execstr = "set foldlevel=" . foldlevel(l:fstart) + exec l:execstr + call SortRange(l:fstart + 1,l:fend,a:dir) + call cursor(line("$"),0) + del x + loadview + call cursor(l:oldcursor,0) +endfunction +"}}}3 +"}}}2 +" MakeChars() {{{2 +" Make a string of characters +" Used for strings of repeated characters +function MakeChars(count,char) + let i = 0 + let l:chars="" + while i < a:count + let l:chars = l:chars . a:char + let i = i + 1 + endwhile + return l:chars +endfunction +"}}}2 +" MakeSpaces() {{{2 +" Make a string of spaces +function MakeSpaces(count) + return MakeChars(a:count," ") +endfunction +"}}}2 +" MakeDashes() {{{2 +" Make a string of dashes +function MakeDashes(count) + return MakeChars(a:count,"-") +endfunction +"}}}2 +" MyFoldText() {{{2 +" Create string used for folded text blocks +function MyFoldText() + if exists('g:vo_fold_length') && g:vo_fold_length == "max" + let l:foldlength = winwidth(0) - 1 - &numberwidth - &foldcolumn + elseif exists('g:vo_fold_length') + let l:foldlength = g:vo_fold_length + else + let l:foldlength = 58 + endif + " I have this as an option, if the user wants to set "…" as the padding + " string, or some other string, like "(more)" + if exists('g:vo_trim_string') + let l:trimstr = g:vo_trim_string + else + let l:trimstr = "..." + endif + let l:MySpaces = MakeSpaces(&sw) + let l:line = getline(v:foldstart) + let l:bodyTextFlag=0 + if l:line =~ "^\t* \\S" || l:line =~ "^\t*\:" + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[TEXT]" + elseif l:line =~ "^\t*\;" + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[TEXT BLOCK]" + elseif l:line =~ "^\t*\> " + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER]" + elseif l:line =~ "^\t*\>" + let l:ls = stridx(l:line,">") + let l:le = stridx(l:line," ") + if l:le == -1 + let l:l = strpart(l:line, l:ls+1) + else + let l:l = strpart(l:line, l:ls+1, l:le-l:ls-1) + endif + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER ".l:l."]" + elseif l:line =~ "^\t*\< " + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER BLOCK]" + elseif l:line =~ "^\t*\<" + let l:ls = stridx(l:line,"<") + let l:le = stridx(l:line," ") + if l:le == -1 + let l:l = strpart(l:line, l:ls+1) + else + let l:l = strpart(l:line, l:ls+1, l:le-l:ls-1) + endif + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER BLOCK ".l:l."]" + elseif l:line =~ "^\t*\|" + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[TABLE]" + endif + let l:sub = substitute(l:line,'\t',l:MySpaces,'g') + let l:sublen = strdisplaywidth(l:sub) + let l:end = " (" . ((v:foldend + l:bodyTextFlag)- v:foldstart) + if ((v:foldend + l:bodyTextFlag)- v:foldstart) == 1 + let l:end = l:end . " line)" + else + let l:end = l:end . " lines)" + endif + let l:endlen = strdisplaywidth(l:end) + + " Multiple cases: + " (1) Full padding with ellipse (...) or user defined string, + " (2) No point in padding, pad would just obscure the end of text, + " (3) Don't pad and use dashes to fill up the space. + if l:endlen + l:sublen > l:foldlength + let l:sub = strpart(l:sub, 0, l:foldlength - l:endlen - strdisplaywidth(l:trimstr)) + let l:sub = l:sub . l:trimstr + let l:sublen = strdisplaywidth(l:sub) + let l:sub = l:sub . l:end + elseif l:endlen + l:sublen == l:foldlength + let l:sub = l:sub . l:end + else + let l:sub = l:sub . " " . MakeDashes(l:foldlength - l:endlen - l:sublen - 1) . l:end + endif + return l:sub.repeat(' ', winwidth(0)-strdisplaywidth(l:sub)) +endfunction +"}}}2 +" InsertDate() {{{2 +" Insert today's date. +function InsertDate(ba) + let @x = strftime("%Y-%m-%d") + if a:ba == "0" + normal! "xp + else + normal! "xP + endif +endfunction +"}}}2 +" InsertSpaceDate() {{{2 +" Insert a space, then today's date. +function InsertSpaceDate() + let @x = " " + let @x = @x . strftime("%Y-%m-%d") + normal! "xp +endfunction +"}}}2 +" InsertTime() {{{2 +" Insert the time. +function InsertTime(ba) + let @x = strftime("%H:%M:%S") + if a:ba == "0" + normal! "xp + else + normal! "xP + endif +endfunction +"}}}2 +" InsertSpaceTime() {{{2 +" Insert a space, then the time. +function InsertSpaceTime() + let @x = " " + let @x = @x . strftime("%H:%M:%S") + normal! "xp +endfunction +"}}}2 +" Ind(line) {{{2 +" Determine the indent level of a line. +" Courtesy of Gabriel Horner +function! Ind(line) + return indent(a:line)/&tabstop +endfunction +"}}}2 +" BodyText(line) {{{2 +" Determine the indent level of a line. +function! BodyText(line) + return (match(getline(a:line),"^\t*:") == 0) +endfunction +"}}}2 +" PreformattedBodyText(line) {{{2 +" Determine the indent level of a line. +function! PreformattedBodyText(line) + return (match(getline(a:line),"^\t*;") == 0) +endfunction +"}}}2 +" PreformattedUserText(line) {{{2 +" Determine the indent level of a line. +function! PreformattedUserText(line) + return (match(getline(a:line),"^\t*<") == 0) +endfunction +"}}}2 +" PreformattedUserTextLabeled(line) {{{2 +" Determine the indent level of a line. +function! PreformattedUserTextLabeled(line) + return (match(getline(a:line),"^\t*<\S") == 0) +endfunction +"}}}2 +" PreformattedUserTextSpace(line) {{{2 +" Determine the indent level of a line. +function! PreformattedUserTextSpace(line) + return (match(getline(a:line),"^\t*< ") == 0) +endfunction +"}}}2 +" UserText(line) {{{2 +" Determine the indent level of a line. +function! UserText(line) + return (match(getline(a:line),"^\t*>") == 0) +endfunction +"}}}2 +" UserTextSpace(line) {{{2 +" Determine the indent level of a line. +function! UserTextSpace(line) + return (match(getline(a:line),"^\t*> ") == 0) +endfunction +"}}}2 +" UserTextLabeled(line) {{{2 +" Determine the indent level of a line. +function! UserTextLabeled(line) + return (match(getline(a:line),"^\t*>\S") == 0) +endfunction +"}}}2 +" PreformattedTable(line) {{{2 +" Determine the indent level of a line. +function! PreformattedTable(line) + return (match(getline(a:line),"^\t*|") == 0) +endfunction +"}}}2 +" MyFoldLevel(Line) {{{2 +" Determine the fold level of a line. +function MyFoldLevel(line) + let l:myindent = Ind(a:line) + let l:nextindent = Ind(a:line+1) + + if BodyText(a:line) + if (BodyText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (BodyText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedBodyText(a:line) + if (PreformattedBodyText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedBodyText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedTable(a:line) + if (PreformattedTable(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedTable(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedUserText(a:line) + if (PreformattedUserText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedUserTextSpace(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedUserTextLabeled(a:line) + if (PreformattedUserTextLabeled(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedUserText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif UserText(a:line) + if (UserText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (UserTextSpace(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif UserTextLabeled(a:line) + if (UserTextLabeled(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (UserText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + else + if l:myindent < l:nextindent + return '>'.(l:myindent+1) + endif + if l:myindent > l:nextindent + "return '<'.(l:nextindent+1) + return (l:myindent) + "return '<'.(l:nextindent-1) + endif + return l:myindent + endif +endfunction +"}}}2 +" Spawn(line) {{{2 +" Execute an executable line +" Courtesy of Steve Litt +if !exists("loaded_steveoutliner_functions") + let loaded_steveoutliner_functions=1 +function Spawn() + let theline=getline(line(".")) + let idx=matchend(theline, "_exe_\\s*") + if idx == -1 + echo "Not an executable line" + else + let command=strpart(theline, idx) + let command="!".command + exec command + endif +endfunction +endif +"}}}2 +" This should be a setlocal but that doesn't work when switching to a new .otl file +" within the same buffer. Using :e has demonstrated this. +set foldtext=MyFoldText() + +"setlocal fillchars=|, + +endif " if !exists("loaded_vimoutliner_functions") +" End Vim Outliner Functions + +" Menu Entries {{{1 +" VO menu +amenu &VO.Expand\ Level\ &1 :set foldlevel=0 +amenu &VO.Expand\ Level\ &2 :set foldlevel=1 +amenu &VO.Expand\ Level\ &3 :set foldlevel=2 +amenu &VO.Expand\ Level\ &4 :set foldlevel=3 +amenu &VO.Expand\ Level\ &5 :set foldlevel=4 +amenu &VO.Expand\ Level\ &6 :set foldlevel=5 +amenu &VO.Expand\ Level\ &7 :set foldlevel=6 +amenu &VO.Expand\ Level\ &8 :set foldlevel=7 +amenu &VO.Expand\ Level\ &9 :set foldlevel=8 +amenu &VO.Expand\ Level\ &All :set foldlevel=99999 +amenu &VO.-Sep1- : +"Tools sub-menu +let s:path2scripts = expand(':p:h:h').'/vimoutliner/scripts' +" otl2html +exec 'amenu &VO.&Tools.otl2&html\.py\ (otl2html\.py\ thisfile\ -S\ html2otl_nnnnnn\.css\ >\ thisfile\.html) :!'.s:path2scripts.'/otl2html.py -S html2otl_nnnnnn.css % > %.html' +" otl2docbook +exec 'amenu &VO.&Tools.otl2&docbook\.pl\ (otl2docbook\.pl\ thisfile\ >\ thisfile\.dbk) :!'.s:path2scripts.'/otl2docbook.pl % > %.dbk' +" otl2table +exec 'amenu &VO.&Tools.otl2&table\.py\ (otl2table\.py\ thisfile\ >\ thisfile\.txt) :!'.s:path2scripts.'/otl2table.py % > %.txt' +" otl2tags => FreeMind +exec 'amenu &VO.&Tools.otl2tags\.py\ =>\ &FreeMind\ (otl2tags\.py\ \-c\ otl2tags_freemind\.conf\ thisfile\ >\ thisfile\.mm) :!'.s:path2scripts.'/otl2tags.py -c '.s:path2scripts.'/otl2tags_freemind.conf % > %.mm' +" otl2tags => Graphviz +exec 'amenu &VO.&Tools.otl2tags\.py\ =>\ &Graphviz\ (otl2tags\.py\ \-c\ otl2tags_graphviz\.conf\ thisfile\ >\ thisfile\.gv) :!'.s:path2scripts.'/otl2tags.py -c '.s:path2scripts.'/otl2tags_graphviz.conf % > %.gv' +amenu &VO.&Tools.&myotl2thml\.sh\ (myotl2html\.sh\ thisfile) :!myotl2html.sh % +amenu &VO.-Sep2- : +amenu &VO.&Color\ Scheme :popup Edit.Color\ Scheme +amenu &VO.-Sep3- : +amenu &VO.&Help.&Index :he vo +amenu &VO.&Help.&,,\ Commands :he votl-command +amenu &VO.&Help.&Checkboxes :he votl-checkbox +amenu &VO.&Help.&Hoisting :he votl-hoisting +amenu &Help.-Sep1- : +" Help menu additions +amenu &Help.&Vim\ Outliner.&Index :he votl +amenu &Help.&Vim\ Outliner.&,,\ Commands :he votl-command +amenu &Help.&Vim\ Outliner.&Checkboxes :he votl-checkbox +amenu &Help.&Vim\ Outliner.&Hoisting :he votl-hoisting +"}}}1 +" Auto-commands {{{1 +if !exists("autocommand_vo_loaded") + let autocommand_vo_loaded = 1 + au BufNewFile,BufRead *.otl setf votl +" au CursorHold *.otl syn sync fromstart + "set updatetime=500 +endif +"}}}1 + +" this command needs to be run every time so Vim doesn't forget where to look +setlocal tags^=$HOME/.vim/vimoutliner/vo_tags.tag + +" Added an indication of current syntax as per Dillon Jones' request +let b:current_syntax = "outliner" + +" Directory where VO is located now +let vo_dir = expand(":p:h:h") + +" Load rc file, only the first found. +let rcs = split(globpath('$HOME,$HOME/.vimoutliner','.vimoutlinerrc'), "\n") + + \ split(globpath('$HOME,$HOME/.vimoutliner,$HOME/.vim', 'vimoutlinerrc'), "\n") + + \ split(globpath(vo_dir, 'vimoutlinerrc'), "\n") + +if len(rcs) > 0 + exec 'source '.rcs[0] +else + runtime vimoutliner/vimoutlinerrc +endif +" Load modules +if exists('g:vo_modules_load') + for vo_module in split(g:vo_modules_load, '\s*:\s*') + exec "runtime! vimoutliner/plugin/votl_" . vo_module . ".vim" + endfor +unlet! vo_module +endif + +" Vim Outliner Key Mappings {{{1 +" insert the date +nmap d $:call InsertSpaceDate() +imap d ~x:call InsertDate(0)a +nmap D ^:call InsertDate(1)a + +" insert the time +nmap t $:call InsertSpaceTime() +imap t ~x:call InsertTime(0)a +nmap T ^:call InsertTime(1)a + +" sort a list naturally +map s :silent call SortChildren(0) +" sort a list, but you supply the options +map S :silent call SortChildren(1) + +" invoke the file explorer +map f :e . +imap f :e . + +" Insert a fence for segmented lists. +" this divider is used by otl2html.py to create '
' +map - o----------------------------------------0 +imap - ---------------------------------------- + +" switch document between the two types of bodytext styles +if use_space_colon == 1 + " First, convert document to the marker style + map b :%s/\(^\t*\) :/\1/e:%s/\(^\t*\) /\1 : /e:let @/="" + " Now, convert document to the space style + map B :%s/\(^\t*\) :/\1/e:let @/="" +else + " First, convert document to the marker style + map b :%s/\(^\t*\):/\1/e:%s/\(^\t*\) /\1: /e:let @/="" + " Now, convert document to the space style + map B :%s/\(^\t*\):/\1/e:let @/="" +endif + +" Steve's additional mappings start here +map +map +map 0 :set foldlevel=99999 +map 9 :set foldlevel=8 +map 8 :set foldlevel=7 +map 7 :set foldlevel=6 +map 6 :set foldlevel=5 +map 5 :set foldlevel=4 +map 4 :set foldlevel=3 +map 3 :set foldlevel=2 +map 2 :set foldlevel=1 +map 1 :set foldlevel=0 +"next line commented out due to hard-coded nature and ancient, nonexistent file +"map ,, :runtime vimoutliner/vimoutlinerrc +map! w :wa +nmap e :call Spawn() +" Steve's additional mappings end here + +" End of Vim Outliner Key Mappings }}}1 + +" The End +" vim600: set foldmethod=marker foldlevel=0: diff --git a/pack/acp/start/vimoutliner/install.sh b/pack/acp/start/vimoutliner/install.sh new file mode 100755 index 0000000..254b828 --- /dev/null +++ b/pack/acp/start/vimoutliner/install.sh @@ -0,0 +1,173 @@ +#!/bin/bash + +homedir=$HOME +vimdir=$homedir/.vim +vodir=$vimdir/vimoutliner +OS=`uname` + +backupargs="" + + +#SOME FUNCTIONS +sure () { + read REPLY + echo test $REPLY = "y" || test $REPLY = "Y" +} + +make_dir () { + test -d $1 || { + echo " creating: $1" + mkdir $1 + created=1 + } +} + +copyfile () { + echo " installing: $2/$1" + install $backupargs $1 $2/$1 +} + +copydir () { + files=`ls $1` + for i in $files; do + echo " installing: $2/$i" + if [ -d $1/$i ]; then + mkdir -p $2/$i + copydir $1/$i $2/$i + else + install $backupargs $1/$i $2 + fi + done +} + +#START THE INSTALLATION +cat <> $homedir/.vimrc + } +egrep -lq "syntax[[:space:]]+on" $homedir/.vimrc || \ + { modified=1 + echo "syntax on" >> $homedir/.vimrc + } +if [ $modified -eq 0 ] ; then + echo " not modified"; +else + echo " modifying $homedir/.vimrc" +fi + +#TWEAK $HOME/.vim/filetype.vim +modified=0 +echo checking/creating/modifying $homedir/.vim/filetype.vim +test -f $homedir/.vim/filetype.vim || \ + { echo " creating $homedir/.vim/filetype.vim" + touch $homedir/.vim/filetype.vim + } +egrep -lq "runtime\! ftdetect/\*.vim" $homedir/.vim/filetype.vim || \ + { echo " modifying $homedir/.vim/filetype.vim" + modified=1 + echo "runtime! ftdetect/*.vim" >> $homedir/.vim/filetype.vim + } +if [ $modified -eq 0 ] ; then echo " not modified"; fi + +#CLEANUP OLD INSTALLATIONS +echo "cleaning up old (<0.3.5) installations" +files=`find $vimdir -iname "vo_*"` +for file in $files; do + echo "removing $file" + rm -v $file +done + +#CLEANUP OLD BACKUPS +if [ -z $backupargs ]; then + echo "cleaning up old backups" + files=`find $vimdir -iname "vo*.old"` + for file in $files; do + echo "removing $file" + rm -v $file + done + files2=`find $vodir -iname "*.old"` + for file in $files; do + echo "removing $file" + rm -v $file + done +fi + +#COPY FILES +echo "installing files" +copyfile syntax/votl.vim $vimdir +copyfile ftplugin/votl.vim $vimdir +copyfile ftdetect/votl.vim $vimdir +copyfile colors/vo_light.vim $vimdir +copyfile colors/vo_dark.vim $vimdir +copyfile doc/votl.txt $vimdir +copyfile doc/votl_cheatsheet.txt $vimdir +copyfile vimoutlinerrc $vodir +copyfile vimoutliner/scripts/votl_maketags.pl $vimdir + +#INCORPORATE HELP DOCUMENTATION +echo "Installing vimoutliner documentation" +vim -c "helptags $HOME/.vim/doc" -c q + +#INSTALL THE ADD-ONS +cat <. +"# +"# Steve Litt, slitt@troubleshooters.com, http://www.troubleshooters.com +"######################################################################### + +" HISTORY {{{1 +"######################################################################### +"# V0.1.0 Pre-alpha +"# Set of outliner friendly settings +"# Steve Litt, 5/28/2001 +"# End of version 0.1.0 +"# +"# V0.1.1 Pre-alpha +"# No change +"# +"# Steve Litt, 5/28/2001 +"# End of version 0.1.1 +"# +"# V0.1.2 Pre-alpha +"# No Change +"# Steve Litt, 5/30/2001 +"# End of version 0.1.2 +"# V0.1.3 Pre-alpha +"# No Change +"# Steve Litt, 5/30/2001 +"# End of version 0.1.3 +"# V0.2.0 +"# Noel Henson adds code for outliner-friendly expand and +"# collapse, comma comma commands, color coding, hooks for a +"# spellchecker, sorting, and date insertion. +"# Noel Henson, 11/24/2002 +"# End of version 0.2.0 +"# END OF HISTORY +"# +"######################################################################### + +" Colors linked {{{1 +" Bill Powell, http://www.billpowellisalive.com +" Linked colors to normal groups. Different schemes will need tweaking. +" Occasionally certain groups will be rendered invisible. ;) +" +" Changelog {{{2 +"2007 Jan 23, 21:23 Tue - 0.3.0, Modified version 0.1 + " Linked syntax groups to standard Vim color groups, intsead of to + " particular colors. Now each colorscheme can work its own magic on + " a VO file. +"2007 Apr 30, 9:36 Mon - 0.3.0, Modified version 0.2 + " Changed a few linked groups to reduce chances of groups being invisible. + " No longer use Ignore group for anything. + " Still a little redundancy; different groups might linked to same color group. + " E.g., PT1 and UT1. But some color schemes (e.g. astronout) will differentiate between + " Special and Debug. Others will use the same colors for, say, Identifier and Debug. + " It just depends. + " To tweak these groups, try :h syntax and go to group-name. + " This shows the color groups, highlighted in your current colorscheme. +" }}} +hi link OL1 Statement +hi link OL2 Identifier +hi link OL3 Constant +hi link OL4 PreProc +hi link OL5 Statement +hi link OL6 Identifier +hi link OL7 Constant +hi link OL8 PreProc +hi link OL9 Statement + +"colors for tags +"hi link outlTags Tag +hi link outlTags Todo + +"color for body text +hi link BT1 Comment +hi link BT2 Comment +hi link BT3 Comment +hi link BT4 Comment +hi link BT5 Comment +hi link BT6 Comment +hi link BT7 Comment +hi link BT8 Comment +hi link BT9 Comment + +"color for pre-formatted text +hi link PT1 Special +hi link PT2 Special +hi link PT3 Special +hi link PT4 Special +hi link PT5 Special +hi link PT6 Special +hi link PT7 Special +hi link PT8 Special +hi link PT9 Special + +"color for tables +hi link TA1 Type +hi link TA2 Type +hi link TA3 Type +hi link TA4 Type +hi link TA5 Type +hi link TA6 Type +hi link TA7 Type +hi link TA8 Type +hi link TA9 Type + +"color for user text (wrapping) +hi link UT1 Debug +hi link UT2 Debug +hi link UT3 Debug +hi link UT4 Debug +hi link UT5 Debug +hi link UT6 Debug +hi link UT7 Debug +hi link UT8 Debug +hi link UT9 Debug + +"color for user text (non-wrapping) +hi link UB1 Underlined +hi link UB2 Underlined +hi link UB3 Underlined +hi link UB4 Underlined +hi link UB5 Underlined +hi link UB6 Underlined +hi link UB7 Underlined +hi link UB8 Underlined +hi link UB9 Underlined + +"colors for folded sections +"hi link Folded Special +"hi link FoldColumn Type + +"colors for experimental spelling error highlighting +"this only works for spellfix.vim with will be cease to exist soon +hi link spellErr Error +hi link BadWord Todo + +" Syntax {{{1 +syn clear +syn sync fromstart + +syn match outlTags '_tag_\w*' contained + +" Noel's style of body text {{{2 +syntax region BT1 start=+^ \S+ skip=+^ \S+ end=+^\S+me=e-1 end=+^\(\t\)\{1}\S+me=e-2 contains=spellErr,SpellErrors,BadWord contained +syntax region BT2 start=+^\(\t\)\{1} \S+ skip=+^\(\t\)\{1} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT3 start=+^\(\t\)\{2} \S+ skip=+^\(\t\)\{2} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT4 start=+^\(\t\)\{3} \S+ skip=+^\(\t\)\{3} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT5 start=+^\(\t\)\{4} \S+ skip=+^\(\t\)\{4} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT6 start=+^\(\t\)\{5} \S+ skip=+^\(\t\)\{5} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT7 start=+^\(\t\)\{6} \S+ skip=+^\(\t\)\{6} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT8 start=+^\(\t\)\{7} \S+ skip=+^\(\t\)\{7} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT9 start=+^\(\t\)\{8} \S+ skip=+^\(\t\)\{8} \S+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained + +"comment-style bodytext as per Steve Litt {{{2 +syntax region BT1 start=+^:+ skip=+^:+ end=+^\S+me=e-1 end=+^\(\t\)\{1}\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT2 start=+^\(\t\)\{1}:+ skip=+^\(\t\)\{1}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT3 start=+^\(\t\)\{2}:+ skip=+^\(\t\)\{2}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT4 start=+^\(\t\)\{3}:+ skip=+^\(\t\)\{3}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT5 start=+^\(\t\)\{4}:+ skip=+^\(\t\)\{4}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT6 start=+^\(\t\)\{5}:+ skip=+^\(\t\)\{5}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT7 start=+^\(\t\)\{6}:+ skip=+^\(\t\)\{6}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT8 start=+^\(\t\)\{7}:+ skip=+^\(\t\)\{7}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region BT9 start=+^\(\t\)\{8}:+ skip=+^\(\t\)\{8}:+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained + +"Preformatted body text {{{2 +syntax region PT1 start=+^;+ skip=+^;+ end=+^\S+me=e-1 end=+^\(\t\)\{1}\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT2 start=+^\(\t\)\{1};+ skip=+^\(\t\)\{1};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT3 start=+^\(\t\)\{2};+ skip=+^\(\t\)\{2};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT4 start=+^\(\t\)\{3};+ skip=+^\(\t\)\{3};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT5 start=+^\(\t\)\{4};+ skip=+^\(\t\)\{4};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT6 start=+^\(\t\)\{5};+ skip=+^\(\t\)\{5};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT7 start=+^\(\t\)\{6};+ skip=+^\(\t\)\{6};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT8 start=+^\(\t\)\{7};+ skip=+^\(\t\)\{7};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region PT9 start=+^\(\t\)\{8};+ skip=+^\(\t\)\{8};+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained + +"Preformatted tables {{{2 +syntax region TA1 start=+^|+ skip=+^|+ end=+^\S+me=e-1 end=+^\(\t\)\{1}\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA2 start=+^\(\t\)\{1}|+ skip=+^\(\t\)\{1}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA3 start=+^\(\t\)\{2}|+ skip=+^\(\t\)\{2}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA4 start=+^\(\t\)\{3}|+ skip=+^\(\t\)\{3}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA5 start=+^\(\t\)\{4}|+ skip=+^\(\t\)\{4}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA6 start=+^\(\t\)\{5}|+ skip=+^\(\t\)\{5}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA7 start=+^\(\t\)\{6}|+ skip=+^\(\t\)\{6}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA8 start=+^\(\t\)\{7}|+ skip=+^\(\t\)\{7}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region TA9 start=+^\(\t\)\{8}|+ skip=+^\(\t\)\{8}|+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained + +"wrapping user text {{{2 +syntax region UT1 start=+^>+ skip=+^>+ end=+^\S+me=e-1 end=+^\(\t\)\{1}\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT2 start=+^\(\t\)\{1}>+ skip=+^\(\t\)\{1}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT3 start=+^\(\t\)\{2}>+ skip=+^\(\t\)\{2}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT4 start=+^\(\t\)\{3}>+ skip=+^\(\t\)\{3}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT5 start=+^\(\t\)\{4}>+ skip=+^\(\t\)\{4}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT6 start=+^\(\t\)\{5}>+ skip=+^\(\t\)\{5}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT7 start=+^\(\t\)\{6}>+ skip=+^\(\t\)\{6}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT8 start=+^\(\t\)\{7}>+ skip=+^\(\t\)\{7}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UT9 start=+^\(\t\)\{8}>+ skip=+^\(\t\)\{8}>+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained + +"non-wrapping user text {{{2 +syntax region UB1 start=+^<+ skip=+^<+ end=+^\S+me=e-1 end=+^\(\t\)\{1}\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB2 start=+^\(\t\)\{1}<+ skip=+^\(\t\)\{1}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB3 start=+^\(\t\)\{2}<+ skip=+^\(\t\)\{2}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB4 start=+^\(\t\)\{3}<+ skip=+^\(\t\)\{3}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB5 start=+^\(\t\)\{4}<+ skip=+^\(\t\)\{4}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB6 start=+^\(\t\)\{5}<+ skip=+^\(\t\)\{5}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB7 start=+^\(\t\)\{6}<+ skip=+^\(\t\)\{6}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB8 start=+^\(\t\)\{7}<+ skip=+^\(\t\)\{7}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained +syntax region UB9 start=+^\(\t\)\{8}<+ skip=+^\(\t\)\{8}<+ end=+^\(\t\)*\S+me=s-1 contains=spellErr,SpellErrors,BadWord contained + +"comment-style bodytext formatting as per Steve Litt +syntax match Comment "^\s*:.*$" +setlocal fo-=t fo+=crqno +setlocal com=sO:\:\ -,mO:\:\ \ ,eO:\:\:,:\:,sO:\>\ -,mO:\>\ \ ,eO:\>\>,:\> + +" Headings {{{2 +syntax region OL1 start=+^[^:\t]+ end=+^[^:\t]+me=e-1 contains=outlTags,BT1,BT2,PT1,PT2,TA1,TA2,UT1,UT2,UB1,UB2,spellErr,SpellErrors,BadWord,OL2 keepend +syntax region OL2 start=+^\t[^:\t]+ end=+^\t[^:\t]+me=s-1 contains=outlTags,BT2,BT3,PT2,PT3,TA2,TA3,UT2,UT3,UB2,UB3,spellErr,SpellErrors,BadWord,OL3 keepend +syntax region OL3 start=+^\(\t\)\{2}[^:\t]+ end=+^\(\t\)\{2}[^:\t]+me=e-3 contains=outlTags,BT3,BT4,PT3,PT4,TA3,TA4,UT3,UT4,UB3,UB4,spellErr,SpellErrors,BadWord,OL4 keepend +syntax region OL4 start=+^\(\t\)\{3}[^:\t]+ end=+^\(\t\)\{3}[^:\t]+me=e-4 contains=outlTags,BT4,BT5,PT4,PT5,TA4,TA5,UT4,UT5,UB4,UB5,spellErr,SpellErrors,BadWord,OL5 keepend +syntax region OL5 start=+^\(\t\)\{4}[^:\t]+ end=+^\(\t\)\{4}[^:\t]+me=e-5 contains=outlTags,BT5,BT6,PT5,PT6,TA5,TA6,UT5,UT6,UB5,UB6,spellErr,SpellErrors,BadWord,OL6 keepend +syntax region OL6 start=+^\(\t\)\{5}[^:\t]+ end=+^\(\t\)\{5}[^:\t]+me=e-6 contains=outlTags,BT6,BT7,PT6,PT7,TA6,TA7,UT6,UT7,UB6,UB7,spellErr,SpellErrors,BadWord,OL7 keepend +syntax region OL7 start=+^\(\t\)\{6}[^:\t]+ end=+^\(\t\)\{6}[^:\t]+me=e-7 contains=outlTags,BT7,BT8,PT7,PT8,TA7,TA8,UT7,UT8,UB7,UB8,spellErr,SpellErrors,BadWord,OL8 keepend +syntax region OL8 start=+^\(\t\)\{7}[^:\t]+ end=+^\(\t\)\{7}[^:\t]+me=e-8 contains=outlTags,BT8,BT9,PT8,PT9,TA8,TA9,UT8,UT9,UB8,UB9,spellErr,SpellErrors,BadWord,OL9 keepend +syntax region OL9 start=+^\(\t\)\{8}[^:\t]+ end=+^\(\t\)\{8}[^:\t]+me=e-9 contains=outlTags,BT9,PT9,TA9,UT9,UB9,spellErr,SpellErrors,BadWord keepend + +" Auto-commands {{{1 +if !exists("autocommand_vo_loaded") + let autocommand_vo_loaded = 1 + au BufNewFile,BufRead *.otl setf outliner +" au CursorHold *.otl syn sync fromstart +" set updatetime=500 +endif + +" The End +" vim600: set foldmethod=marker foldlevel=0: diff --git a/pack/acp/start/vimoutliner/vimoutliner/images/Vimoutliner_logo.png b/pack/acp/start/vimoutliner/vimoutliner/images/Vimoutliner_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5831d93a7d83bcd4bd030e7955c06cb86b32f697 GIT binary patch literal 19060 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 V5u0KSk&gfX002ovPDHLkV1nsl(4GJQ literal 0 HcmV?d00001 diff --git a/pack/acp/start/vimoutliner/vimoutliner/images/Vimoutliner_logo_tiny.png b/pack/acp/start/vimoutliner/vimoutliner/images/Vimoutliner_logo_tiny.png new file mode 100644 index 0000000000000000000000000000000000000000..4c942ada9e69e008a5c81ae6cd4f683049a4e943 GIT binary patch literal 7036 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 L4K->Jj`9Bk?m-Q2 literal 0 HcmV?d00001 diff --git a/pack/acp/start/vimoutliner/vimoutliner/images/favicon.ico b/pack/acp/start/vimoutliner/vimoutliner/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fd42fabfcd72a56d5648e3392be574a7161543bc GIT binary patch literal 318 zcmZ|HJxfAi0LAhD1tBHW3%x>vZWGEoDQE(a@VTw$v2&Y7m7}ItZ;n5jM0n zgf`R|eS-)hFc3~sLXkW?q0XJ{qLKO~Z_7xZt9ol2J5{}H zqgbsKtJ24`UJJ%N+n>ktRMbYTjmPa%86E~8mj&Me--18e?F@q-1U~>dAWK&VILpG` GJ^TS%#eDz( literal 0 HcmV?d00001 diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.otl b/pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.otl new file mode 100644 index 0000000..9b0dd67 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.otl @@ -0,0 +1,77 @@ +Hoisting +What is it? + : Hoisting is a way to focus on a particular area of an outline. Only the + : offspring from a selected parent will be shown. The offspring are + : left-justified just as if they were the top level headings and had no + : parent. +Installation + The hoist plugin is included in the VimOutliner plugin directory + This plugin is disabled by default + See information in the ~/.vimoutlinerrc on how to enable it + Optionally set the hoistParanoia variable + : If you are really paranoid about loosing your data during shakedown + : of vo_hoist.vim, you can add this to your ~/.vimoutlinerrc file. It + : will prevent VO from automatically removing the temporary hoist + : files. This will have a tendency to hugely increase the number of + : files in your working directory (but if you're paranoid... ;) ) + let g:hoistParanoia = 1 +How do I use it? + Hoisting + : Whenever you open a VO document, hoisting will be available. + Invocation + Place the cursor on the parent to be hoisted + ,,h + You will need to hit to accept some informational messages + You should now see the children of the selected parent ready for editing + Treat this document just like a normal .otl file + De-hoisting + : From within the hoisted document you simply need to quit. The + : hoisted data will be saved in place of the old children. The cursor + : will be returned to the hoisted parent. + Invocation + The :q, :wq, :x and ZZ perform a de-hoist operation + A write will automatically be done to save any changes + Manual De-hoisting + : Should the de-hoisting ever fail or should an operator quit Vim (by + : closing the window with the mouse, say), a manual de-hoisting will + : need to be performed. + You can find a currently hoisted parent by searching for __hoist + Place the cursor on the parent with the __hoist tag + ,,H + The edited, hoisted offspring will replace the current offspring + The __hoist tag will be removed +The Hoist Tag + Example Tag + : The hoist tag is added to a hoisted parent for error recovery. It + : includes a filename, a line number and a timestamp. + Example Tag + __hoist:vo_hoist.46.20030816124249.otl + Tag Components + Tag Marker + __hoist: + Easy search and replace + Filename Prefix + vo_hoist. + Needed to comply with VO standards for file naming + Parent Line Number (at time of hoisting) + 46. + Timestamp + 20030816124249 + YYYYMMDDhhmmss + Filename Suffix + .otl + Duh +The Log Files + : Log files of the hoists are created to aid in error recovery should that + : become necessary. They are created in the same directory as the working + : .otl file. + Log Filename + .vo_hoist..log + Example Log Filename + .vo_hoist.test.otl.log + Contents + There is one line per hoist operation + Each is comprised of a parent with a __hoist tag +Limitations + 1 Level Deep + : Until debug is complete, hoisting is limited to one level. diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.vim new file mode 100755 index 0000000..c4064d1 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/prev/votl_hoist.vim @@ -0,0 +1,251 @@ +"###################################################################### +"# VimOutliner Hoisting +"# Copyright (C) 2003 by Noel Henson noel@noels-lab.com +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### + +" Load the plugin {{{1 +" mappings {{{1 +map h :call Hoist(line(".")) +map H :call DeHoistThis(line(".")) +"}}}1 +if exists("g:did_vo_hoist") + finish +endif +if !exists("g:hoistParanoia") + let g:hoistParanoia=0 +endif +let g:did_vo_hoist = 1 +" Functions {{{1 +" RemoveTabsLine(line,tabs) {{{2 +" remove specified number of tabs from the beginning of line +function! RemoveTabsLine(line,tabs) + return substitute(getline(a:line),"^\\(\\t\\)\\{".a:tabs."}", "", "") +endfunction +"}}}2 +" MakeTempFilename(line) {{{2 +" return a string to use as the temporary filename for the hoisted area +function! MakeTempFilename(line) + return "vo_hoist.".a:line.strftime(".%Y%m%d%H%M%S").".otl" +endfunction +"}}}2 +" AddHoistFilename(line) {{{2 +" Add a temporary filename to a parent line to indicate hoisting +function! AddHoistFilename(line) + let l:newparent = getline(a:line)." __hoist:".MakeTempFilename(a:line) + call setline(a:line,l:newparent) +endfunction +"}}}2 +"}}}2 +" DeleteHoistFilename(line) {{{2 +" Delete a temporary filename from a parent line +function! DeleteHoistFilename(line) + call setline(a:line,substitute(getline(a:line)," __hoist:.*","","")) +endfunction +"}}}2 +" ExtractHoistFilename(line) {{{2 +" Extract a filename from a hoisted parent +function! ExtractHoistFilename(line) + return substitute(getline(a:line),".* __hoist:","","") +endfunction +"}}}2 +" IsParent(line) {{{2 +" Return 1 if this line is a parent +function! IsParent(line) + return (Ind(a:line)+1) == Ind(a:line+1) +endfunction +"}}}2 +" IsHoistedParent(line) {{{2 +" Return 1 if this line is a parent with hoisted children +function! IsHoistParent(line) + return match(getline(a:line)," __hoist:","") != -1 +endfunction +"}}}2 +" FindParent(line) {{{2 +" Return line if parent, parent line if not +function! FindParent(line) + if IsParent(a:line) + return a:line + else + let l:parentindent = Ind(a:line)-1 + let l:searchline = a:line + while (Ind(l:searchline) != l:parentindent) && (l:searchline > 0) + let l:searchline = l:searchline-1 + endwhile + return l:searchline + endif +endfunction +"}}}2 +" FindLastChild(line) {{{2 +" Return the line number of the last descendent of parent line +function! FindLastChild(line) + let l:parentindent = Ind(a:line) + let l:searchline = a:line+1 + while Ind(l:searchline) > l:parentindent + let l:searchline = l:searchline+1 + endwhile + return l:searchline-1 +endfunction +"}}}2 +"}}}2 +" Hoist(line) {{{2 +" Write the offspring of a parent to a new file, open it and remove the +" leading tabs. +function! Hoist(line) + let l:parent = FindParent(a:line) + if l:parent == 0 + return + endif + call cursor(l:parent,1) + let l:firstline = l:parent+1 + let l:childindent = Ind(l:firstline) + let l:lastline = FindLastChild(l:parent) + let l:filename = MakeTempFilename(l:parent) + echo l:firstline.",".l:lastline."w! ".l:filename + let l:folded = foldclosed(l:parent) + call cursor(l:parent,1) + normal zo + exe l:firstline.",".l:lastline."w! ".l:filename + call AddHoistFilename(l:parent) + silent write + " log what we did in case we need to recover manually + let l:doit = l:parent."write! >> .vo_hoist.".bufname(bufnr("%")).".log" + exe l:doit + let l:parentbuffer = bufnr("%") + "WARNING: switching files + let l:doit = "silent e +%s/^\\\\(\\\t\\\\)\\\\{" + let l:doit = l:doit.l:childindent."}// ".l:filename." | " + let l:doit = l:doit."let b:myParentBuffer = ".l:parentbuffer." | " + let l:doit = l:doit."let b:myParentLine = ".l:parent." | " + let l:doit = l:doit."call cursor(1,1)|" + let l:doit = l:doit."let b:hoisted = 1" + exe l:doit + silent write +endfunction +"}}}2 +" DeleteChildren(line) {{{2 +" Delete the existing offspring of a parent +function! DeleteChildren(line) + let l:parent = FindParent(a:line) + let l:firstline = l:parent+1 + let l:lastline = FindLastChild(l:parent) + exe l:firstline.",".l:lastline."d" +endfunction +"}}}2 +" MakeTabString(n) {{{2 +" Return a string of n tabs +function! MakeTabString(n) + let l:string = "" + let l:i = 0 + while l:i < a:n + let l:string = l:string."\t" + let l:i = l:i +1 + endwhile + return l:string +endfunction +"}}}2 +" AddChildren(line) {{{2 +" Add left-justified children to parent. The filename is extracted from the +" end of the parent line. The parent is assumed to have no children at this +" point. +function! AddChildren(line) + let l:filename = ExtractHoistFilename(a:line) + if filereadable(l:filename) == 1 + if a:line == line("$") + exe "read ".l:filename + if a:line != line("$") + exe a:line+1.",$"." s/^/".MakeTabString(Ind(a:line)+1)."/" + endif + else + exe a:line+1."ma v" + call cursor(a:line,1) + exe "read ".l:filename + if a:line+1 != line("'v") + exe a:line+1.",'v-1"." s/^/".MakeTabString(Ind(a:line)+1)."/" + endif + endif + endif +endfunction +"}}}2 +" DeleteHoistFile(line) {{{2 +" Delete a temporary filename from a parent line +function! DeleteHoistFile(line) + if g:hoistParanoia + return + endif + let l:filename = ExtractHoistFilename(a:line) + call delete(l:filename) + let l:filename = l:filename."~" + call delete(l:filename) +endfunction +"}}}2 +" DeHoistThis(line) {{{2 +" Remove the old children, add the new children and remove the __hoist data +" leading tabs from this file. +function! DeHoistThis(line) + let l:parent = FindParent(a:line) + let l:folded = foldclosed(l:parent) + call cursor(l:parent,1) + if l:folded == l:parent + normal zo + endif + call DeleteChildren(l:parent) + call AddChildren(l:parent) + call DeleteHoistFile(l:parent) + call DeleteHoistFilename(l:parent) + if l:folded == l:parent + normal zc + endif +endfunction +"}}}2 +" DeHoist() {{{2 +" Remove the old children, add the new children and remove the __hoist data +" leading tabs from the calling file. +function! DeHoist() + silent write + if bufexists(b:myParentBuffer) == 0 + return + endif + let l:myParentBuffer = b:myParentBuffer + let l:myParentLine = b:myParentLine + bdelete + " Warning switching files + exe "buffer ".l:myParentBuffer + call cursor(l:myParentLine,1) + let l:parent = FindParent(l:myParentLine) + let l:folded = foldclosed(l:parent) + call cursor(l:parent,1) +" if l:folded == l:parent +" normal zo +" endif + normal zv + silent call DeleteChildren(l:parent) + silent call AddChildren(l:parent) + silent call DeleteHoistFile(l:parent) + silent call DeleteHoistFilename(l:parent) + if l:folded == l:parent + call cursor(l:parent,1) + normal zc + endif + silent write +endfunction +"}}}2 +"}}}1 +" Autocommands {{{1 + au BufReadPost vo_hoist.*.otl cmap wq call DeHoist() + au BufReadPost vo_hoist.*.otl cmap qa call DeHoist() + au BufReadPost vo_hoist.*.otl cmap q call DeHoist() + au BufReadPost vo_hoist.*.otl cmap x call DeHoist() + au BufReadPost vo_hoist.*.otl nmap ZZ :call DeHoist() +"}}}1 +" vim600: set foldlevel=0 foldmethod=marker: diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.otl b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.otl new file mode 100644 index 0000000..0a135b4 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.otl @@ -0,0 +1,310 @@ +Checkboxes: votl_checkbox +What is it? + : Checkboxes is a plugin for project, task and list managment. It add an + : understanding of check boxes and percentage of task completion to Vim + : Outliner. It adds just three tags and six commands. +Installation + This should already be included in your Vim Outliner package + The newest, stable version is included with this package in the plugin directory + The pluging is already enabled in your ~/.vimoutlinerrc +Tag Syntax + [_] an unchecked item or incomplete task + [X] a checked item or complete task + [-] a canceled item - removes this item/branch from completion calculations + % a placeholder for percentage of completion + n% a percentage of completion, used in calculating parent completion + n%w a percentage with a weighting factor - e.g.: 10%2 + [tag] a tag than can be replaced from a list of tags + [tag] also the default tag name - will be replaced by tag[0] of tag list[0] + [tag] [tag] tags must be separated by whitespace +Example g:cbTags (put in .vimoutlinerrc) + let g:cbTags = [ + \ ['TODO','FEEDBACK','VERIFY','DELEGATED','HOLDING'] + \,['Feature','Enhancement','Bug'] + \,['Low','Normal','High','URGENT'] + \,['Home','Lab','Work','Shopping'] + \] +Checkbox Commands + : The default for VimOutliner is ,, so we will use this + : leader in the command discussions. + ,,cb Create a check box + : This works for the current heading or selected range of lines + : including folds. Visual selection of the range of headings works + : nicely. This command is currently not aware of body text. This + : limited awareness needs to be fixed before this plugin can be + : included in the standard Vim Outliner plugins. + ,,cB Create a check box (even if one exists) + ,,c% Create a checkbox and % symbol + : This works just like ,,cb but add a % symbol for use in completion + : calculations. + ,,cp Create a checkbox and % symbol + : This works just like ,,cb but add a % symbol for use in completion + : calculations; even on childless headings. + ,,cx Change check box state + : If there is a checkbox on the line the cursor is on, change its + : state. If it's checked, uncheck it and vice-versa. Then recompute + : the completion of the entire branch starting from the root parent. + ,,cd Delete a checkbox + : Delete the left-most check box on the selected heading(s). + ,,cz Compute completion + : Starting at the heading the cursor is on, recursively compute the + : completion level of all sub-headings. + ,,c1 Set completion to 10% + : Set the completion to 10%, if a percentage already exists. + ,,c2 Set completion to 20% + : Set the completion to 20%, if a percentage already exists. + ,,c3 Set completion to 30% + : Set the completion to 30%, if a percentage already exists. + ,,c4 Set completion to 40% + : Set the completion to 40%, if a percentage already exists. + ,,c5 Set completion to 50% + : Set the completion to 50%, if a percentage already exists. + ,,c6 Set completion to 60% + : Set the completion to 60%, if a percentage already exists. + ,,c7 Set completion to 70% + : Set the completion to 70%, if a percentage already exists. + ,,c8 Set completion to 80% + : Set the completion to 80%, if a percentage already exists. + ,,c9 Set completion to 90% + : Set the completion to 90%, if a percentage already exists. + ,,c+ Increment the completion by 10% + : Increment the completion by 10%, if a percentage already exists. + ,,c- Decrement the completion by 10% + : Decrement the completion by 10%, if a percentage already exists. + ,,ct Set tag to next tag in current tag list + : Set the tag under the cursor to the next tag in the list that + : contains the current tag. This command is not mapped if g:cbTags + : does not exist. + ,,cT Set tag to next tag list + : Set the tag under the cursor to the first tag in the next tag list. + : This command is not mapped if g:cbTags does not exist. +How do I use it? + Start with a simple example + : Let's start with planning a small party; say a barbeque. + Make the initial outline + Barbeque + Guests + Bill and Barb + Larry and Louise + Marty and Mary + Food + Chicken + Ribs + Corn on the cob + Beverages + Soda + Iced Tea + Beer + Party Favors + Squirt guns + Hats + Name tags + Materials + Paper Plates + Napkins + Trash Containers + Add the check boxes + : This can be done by visually selecting them and typing ,,cb. + : When done, you should see this: + [_] Barbeque + [_] Guests + [_] Bill and Barb + [_] Larry and Louise + [_] Marty and Mary + [_] Food + [_] Chicken + [_] Ribs + [_] Corn on the cob + [_] Beverages + [_] Soda + [_] Iced Tea + [_] Beer + [_] Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] Materials + [_] Paper Plates + [_] Napkins + [_] Trash Containers + Now check off what's done + : Checking off what is complete is easy with the ,,cx command. + : Just place the cursor on a heading and ,,cx it. Now you can see + : what's done as long as the outline is fully expanded. + [_] Barbeque + [X] Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [_] Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers + Getting more advanced + Now summarize what's done + : You can summarize what is done with the ,,cz command. Place the + : cursor on the 'Barbeque' heading and ,,cz it. The command will + : recursively process the outline and update the check boxes of + : the parent headlines. You should see: + : (Note: the only change is on the 'Guests' heading. It changed + : because all of its children are complete.) + [_] Barbeque + [X] Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [_] Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers + Add percentages for a better view + : You can get a much better view of what's going on, especially + : with collapsed headings, if you add percentages. Place a 0% on + : each heading that has children like this: + [_] 59% Barbeque + [X] 100% Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [_] 66% Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] 66% Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] 0% Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] 66% Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers + Now compute the percentage of completion + : After adding the 0% symbols, place the cursor on the 'Barbeque' + : heading and execute ,,cz as before. Keep in mind that the + : recursive percentages are weighted. You should see: + [_] 59% Barbeque + [X] 100% Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [_] 66% Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [_] 66% Beverages + [_] Soda + [X] Iced Tea + [X] Beer + [_] 0% Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] 66% Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers + Complete a few more just for fun + : Mark Salad and Soda and recompute with ,,cz and you should + : see the ouline below. + : + : Try playng around with zc and zo to see the effects of opening + : and closing folds. Even if you place the cursor on 'Barbeque' + : and zo it, you still have a good understanding of how complete + : the project is. + [_] 66% Barbeque + [X] 100% Guests + [X] Bill and Barb + [X] Larry and Louise + [X] Marty and Mary + [_] 66% Food + [X] Chicken + [X] Ribs + [_] Corn on the cob + [X] 100% Beverages + [X] Soda + [X] Iced Tea + [X] Beer + [_] 0% Party Favors + [_] Squirt guns + [_] Hats + [_] Name tags + [_] 66% Materials + [X] Paper Plates + [_] Napkins + [X] Trash Containers + Getting way more advanced + Weighted Tasks + Here is a simple outline to track a project + [_] 22% Garage Upgrade + [_] 66% Clean out old junk + [X] 100% empty garage + [X] 100% sort junk + [_] 0% dispose of junk + [_] 0% Build Shelves + [_] 0% Oranize Junk + [_] 0% oranize saved junk + [_] 0% put junk on shelves + What if some tasks take more effort? + : Assume that you know that it will take twice as long to sort + : junk as it does to remove it from the garage or to dispose + : of it. This can be represented with weights. Notice the + : completion percentage of 'Clean out old junk' once a weight + : has been added. Each percentage can be weighted. + [_] 25% Garage Upgrade + [_] 75% Clean out old junk + [X] 100% empty garage + [X] 100%2 sort junk + [_] 0% dispose of junk + [_] 0% Build Shelves + [_] 0% Oranize Junk + [_] 0% oranize saved junk + [_] 0% put junk on shelves + Complex weighting + [_] 83% Garage Upgrade + [_] 75%2 Clean out old junk + [X] 100% empty garage + [X] 100%2 sort junk + [_] 0% dispose of junk + [X] 100%2 Build Shelves + [_] 66% Oranize Junk + [X] 100%2 oranize saved junk + [_] 0% put junk on shelves + Tags: Add more information to a heading + : Additional information and workflow information can easily + : be added to headings with tags. The command ,,ct can be used + : to cycle a tag among it sibling tags in g:cbTags. ,,cT can + : be be used to cycle a tag to a different list of sibling + : tags. + My Software Project + [_] 33% To Do + [X] Misspellings in documention [Bug] [High] + [_] Installation infects all networked systems with app [Feature] [Normal] + [_] Clean garage [Low] [@Home] diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.vim new file mode 100755 index 0000000..e97ae57 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_checkbox.vim @@ -0,0 +1,475 @@ +"###################################################################### +"# VimOutliner Checkboxes +"# Copyright (C) 2003 by Noel Henson noel@noels-lab.com +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### + +" mappings {{{1 +" insert a chechbox +noremap cb :call SafelyInsertCheckBox() +noremap c% :call SafelyInsertCheckBoxPercent() +noremap cp :call SafelyInsertCheckBoxPercentAlways() +noremap cB :call InsertCheckBox() + +" delete a chechbox +noremap cd :call DeleteCheckbox() + +" switch the status of the box and adjust percentages +if !exists('g:vo_checkbox_fast_calc') || g:vo_checkbox_fast_calc == 1 + " Use new and faster method + noremap cx :call SwitchBox() call CalculateMyBranch(line(".")) + noremap c+ :call IncPercent(".") call CalculateMyBranch(line(".")) + noremap c- :call DecPercent(".") call CalculateMyBranch(line(".")) + noremap c1 :call SetPercent(".",10)call CalculateMyBranch(line('.')) + noremap c2 :call SetPercent(".",20)call CalculateMyBranch(line('.')) + noremap c3 :call SetPercent(".",30)call CalculateMyBranch(line('.')) + noremap c4 :call SetPercent(".",40)call CalculateMyBranch(line('.')) + noremap c5 :call SetPercent(".",50)call CalculateMyBranch(line('.')) + noremap c6 :call SetPercent(".",60)call CalculateMyBranch(line('.')) + noremap c7 :call SetPercent(".",70)call CalculateMyBranch(line('.')) + noremap c8 :call SetPercent(".",80)call CalculateMyBranch(line('.')) + noremap c9 :call SetPercent(".",90)call CalculateMyBranch(line('.')) +else + " Use the old method + noremap cx :call SwitchBox() call NewHMD(FindRootParent(line("."))) + noremap c+ :call IncPercent(".") call NewHMD(FindRootParent(line("."))) + noremap c- :call DecPercent(".") call NewHMD(FindRootParent(line("."))) + noremap c1 :call SetPercent(".",10)call NewHMD(FindRootParent(line("."))) + noremap c2 :call SetPercent(".",20)call NewHMD(FindRootParent(line("."))) + noremap c3 :call SetPercent(".",30)call NewHMD(FindRootParent(line("."))) + noremap c4 :call SetPercent(".",40)call NewHMD(FindRootParent(line("."))) + noremap c5 :call SetPercent(".",50)call NewHMD(FindRootParent(line("."))) + noremap c6 :call SetPercent(".",60)call NewHMD(FindRootParent(line("."))) + noremap c7 :call SetPercent(".",70)call NewHMD(FindRootParent(line("."))) + noremap c8 :call SetPercent(".",80)call NewHMD(FindRootParent(line("."))) + noremap c9 :call SetPercent(".",90)call NewHMD(FindRootParent(line("."))) +endif + +" calculate the proportion of work done on the subtree +noremap cz :call NewHMD(FindRootParent(line("."))) + +" tag list key mappings +if exists("g:cbTags") + noremap ct :call SetNextTag() + noremap cT :call SetNextList() +endif + +"}}}1 +" Load guard for functions {{{1 +if exists('s:loaded') + finish +endif +let s:loaded = 1 + +" InsertCheckBox() {{{1 +" Insert a checkbox at the beginning of a header without disturbing the +" current folding. +function! InsertCheckBox() + let @x = "[_] " + normal! ^"xP +endfunction +"}}}1 +" Safely InsertCheckBox() {{{1 +" Insert a checkbox at the beginning of a header without disturbing the +" current folding only if there is no checkbox already. +function! SafelyInsertCheckBox() + if match(getline("."),"^\t\t*\[<>:;|\]") != -1 + return + endif + if match(getline("."),"[\[X_\]]") == -1 + let @x = "[_] " + normal! ^"xP + endif +endfunction +"}}}1 +" Safely InsertCheckBoxPercent() {{{1 +" Insert a checkbox and % sign at the beginning of a header without disturbing +" the current folding only if there is no checkbox already. +function! SafelyInsertCheckBoxPercent() + if match(getline("."),"^\t\t*\[<>:;|\]") != -1 + return + endif + if match(getline("."), "[\[X_\]]") == -1 + if Ind(line(".")+1) > Ind(line(".")) + let @x = "[_] % " + else + let @x = "[_] " + endif + normal! ^"xP + endif +endfunction +"}}}1 +" Safely InsertCheckBoxPercentAlways() {{{1 +" Insert a checkbox and % sign at the beginning of a header without disturbing +" the current folding only if there is no checkbox already. Include the +" checkbox even on childless headings. +function! SafelyInsertCheckBoxPercentAlways() + if match(getline("."),"^\t\t*\[<>:;|\]") != -1 + return + endif + if match(getline("."), "[\[X_\]]") == -1 + let @x = "[_] % " + normal! ^"xP + endif +endfunction +"}}}1 +" SetBox(char) {{{1 +" Switch the state of the checkbox on the current line. +function! SetBox(char) + substitute/\[.\]/\="[".expand(a:char)."]"/ + if a:char == 'X' + call SetPercent(".",100) + elseif a:char == '_' + call SetPercent(".",0) + endif +endfunction + +"}}}1 +" SwitchBox() {{{1 +" Switch the state of the checkbox on the current line. +function! SwitchBox() + let l:line = getline(".") + let questa = strridx(l:line,"[_]") + let questb = strridx(l:line,"[X]") + if (questa != -1) || (questb != -1) + if (questa != -1) + call SetBox('X') + else + call SetBox('_') + endif + endif +endfunction +"}}}1 +" DeleteCheckbox() {{{1 +" Delete a checkbox if one exists +function! DeleteCheckbox() + let questa = strridx(getline("."),"[_]") + let questb = strridx(getline("."),"[X]") + if (questa != -1) || (questb != -1) + if (questa != -1) + substitute/\(^\s*\)\[_\] \(.*\)/\1\2/ + else + substitute/\(^\s*\)\[X\] \(.*\)/\1\2/ + endif + endif +endfunction +"}}}1 +" Ind(line) {{{1 +" Return the index of the line. +" Remove it when using the new version of VO +function! Ind(line) + return indent(a:line) / &tabstop +endf +" FindMyParent(line) {{{1 +" returns the line number of the parent of the current node +function! FindMyParent(line) + let l:mylevel = Ind(a:line) + if l:mylevel == 0 + return (a:line) + endif + let l:i = a:line + while Ind(l:i) >= l:mylevel + let l:i -= 1 + endwhile + return l:i +endf + +" FindRootParent(line) {{{1 +" returns the line number of the root parent for any child +function! FindRootParent(line) + if Ind(a:line) == 0 + return (a:line) + endif + let l:i = a:line + while l:i > 1 && Ind(l:i) > 0 + let l:i = l:i - 1 + endwhile + return l:i +endf + +" LimitPercent(percent) {{{1 +" Limits percentage values to between 0 and 100 +function! LimitPercent(val) + if a:val > 100 + return 100 + elseif a:val < 0 + return 0 + else + return a:val + endif +endf + +" GetPercent(line) {{{1 +" Get the percent complete from a line +function! GetPercent(line) + let l:proportion = 0 + let mbegin=match(getline(a:line), " [0-9]*%") + if mbegin + let mend=matchend(getline(a:line), " [0-9]*%") + let l:proportion=getline(a:line)[mbegin+1 : mend-1] + let l:proportion=str2nr(l:proportion) + endif + return l:proportion +endf + +" SetPercent(line,proportion) {{{1 +" Set the percent complete for a line +function! SetPercent(line,proportion) + let mbegin=match(getline(a:line), " [0-9]*%") + if mbegin + call setline(a:line,substitute(getline(a:line)," [0-9]*%"," ".a:proportion."%","")) + endif +endf + +" IncPercent(line) {{{1 +" Increments the percent doneness by 10% +function! IncPercent(line) + if match(getline(a:line), " [0-9]*%") + call SetPercent(a:line,LimitPercent(GetPercent(a:line)+10)) + endif +endf + +" DecPercent(line) {{{1 +" Decrements the percent doneness by 10% +function! DecPercent(line) + if match(getline(a:line), " [0-9]*%") + let l:percent = GetPercent(a:line) + call setline(a:line,substitute(getline(a:line),"\\[X\\]","[_]","")) + call SetPercent(a:line,LimitPercent(l:percent-10)) + endif +endf + +" ComputePW(line,count,done) {{{1 +" Computes proportion and weight of a node +" Returns (proportion,weight) proportion could be a flag of -1 +function! ComputePW(line,count,done) + let l:proportion=0 + let l:haspercent = 0 + " get the percent + let mbegin=match(getline(a:line), " [0-9]*%") + if mbegin != -1 + let l:haspercent = 1 + let mend=matchend(getline(a:line), " [0-9]*%") + let l:proportion=str2nr(getline(a:line)[mbegin+1 : mend-1]) + endif + " get the weight + let l:weight=1 + let mbegin=match(getline(a:line), "%[0-9]\\+") + if mbegin != -1 + let mend=matchend(getline(a:line), "%[0-9]\\+\s") + let l:weight=str2nr(getline(a:line)[mbegin+1 : mend-1]) + endif + " compute the proportion + if a:count>0 + let l:proportion = ((a:done*100)/a:count)/100 + elseif match(getline(a:line),"\\[X\\]") != -1 + let l:proportion = 100 + elseif match(getline(a:line),"\\[-\\]") != -1 + let l:weight = 0 + endif + " update non-ignored items + let l:questa = strridx(getline(a:line),"[-]") + if l:questa == -1 + call setline(a:line,substitute(getline(a:line)," [0-9]*%"," ".l:proportion."%","")) + endif + " Limit proportion to 0 or 100 if there is not a percentage sign + if !haspercent && (!exists('g:vo_checkbox_fast_calc') || g:vo_checkbox_fast_calc == 1) + let l:proportion = l:proportion == 100 ? l:proportion : 0 + endif + " update the completion + if l:questa != -1 + return [100,l:weight] + elseif l:proportion == 100 + call setline(a:line,substitute(getline(a:line),"\\[_\\]","[X]","")) + return [100,l:weight] + elseif l:proportion == 0 && a:count == 0 + if match(getline(a:line),"\\[X\\]") != -1 + return [100,l:weight] + elseif match(getline(a:line),"\\[_\\]") != -1 + return [0,l:weight] + else + return [-1,l:weight] + endif + else + call setline(a:line,substitute(getline(a:line),"\\[X\\]","[_]","")) + return [l:proportion,l:weight] + endif +endf + +" CalculateMyChildren(line) {{{1 +" Calculates percent completion only on the immediate children of the +" parent specified by line. +function! CalculateMyChildren(line) + let l:done = 0 + let l:count = 0 + let l:line = a:line + 1 + let l:mylevel = Ind(a:line) + let l:childlevel = l:mylevel+1 + while l:mylevel < Ind(l:line) " I have children + if l:childlevel == Ind(l:line) + let l:childstat = ComputePW(l:line,0,0) + let l:childdoneness = l:childstat[0] * l:childstat[1] + if l:childdoneness >= 0 + let l:done += l:childdoneness + let l:count += l:childstat[1] + endif + endif + let l:line += 1 + endwhile + return ComputePW(a:line,l:count,l:done) " returns with (proportion,weight) +endf + +" CalculateMyBranch(line) {{{1 +" Calculate from the leaf, up unlke NewHMD +function! CalculateMyBranch(line) + call NewHMD(a:line) " compute and adjust my children, if I have any + let l:line = a:line + while Ind(l:line) > 0 + let l:line = FindMyParent(l:line) + call CalculateMyChildren(l:line) + endwhile +endf + +" NewHMD(line) {{{1 +" (New How Many Done) +" Calculates proportion of already done work in the subtree +" Recursive, but slow because it computes an entire branch of an outline +" from level 1. +" Returns (proportion,weight) proportion could be a flag of -1 +function! NewHMD(line) + let l:done = 0 + let l:count = 0 + let l:line = a:line+1 + let l:mylevel = Ind(a:line) + let l:childlevel = l:mylevel+1 + while l:mylevel < Ind(l:line) " I have children + if l:childlevel == Ind(l:line) + let l:childstat = NewHMD(l:line) + let l:childdoneness = l:childstat[0] * l:childstat[1] + if l:childdoneness >= 0 + let l:done += l:childdoneness + let l:count += l:childstat[1] + endif + endif + let l:line += 1 + endwhile + return ComputePW(a:line,l:count,l:done) " returns with (proportion,weight) +endf + +" Experimental Heading Tags {{{1 + +if !exists('g:cbTags') + finish +endif + +" GetTag() {{{2 +" return the tag word under the cursor +function! GetTag() + let word = expand("") + if word[0] == '[' && word[-1:] == ']' + return word[1:-2] + endif + return "" +endfunction + +" WhereInLists(word) {{{2 +" return a single-entry list with a pair of values [listIndex,tagIndex] +" return -1,-1 if tag word not found +function! WhereInLists(word) + let lidx = 0 + for list in g:cbTags + let tidx = index(list,a:word) + if tidx >= 0 + return [lidx,tidx] + endif + let lidx += 1 + endfor + return [-1,-1] +endfunction + +" NextTagIdx(lidx,tidx) {{{2 +" return the index of the next tag in the current list +function! NextTagIdx(lidx,tidx) + if a:tidx >= 0 + let llen = len(g:cbTags[a:lidx]) + let tidx = (a:tidx + 1)%llen + endif + return tidx +endfunction + +" GetNextTag(word) {{{2 +" return the next tag word (from a:word) in the list +function! GetNextTag(word) + if a:word == 'tag' + return g:cbTags[0][0] + endif + let liti = WhereInLists(a:word) + if liti[1] == -1 + return "" + endif + let liti[1] = NextTagIdx(liti[0],liti[1]) + let nextword = g:cbTags[liti[0]][liti[1]] + return nextword +endfunction + +" SetNextTag() {{{2 +" set the current tag to the next tag in the same list +" this is circular, the last tag will roll to the first tag +function! SetNextTag() + let oldtag = GetTag() + let newtag = GetNextTag(oldtag) + if newtag == "" + return + endif + let sub = "normal!ci[".newtag + exec sub +endfunction + +" NextListIdx(lidx) {{{2 +" return the index of the next list +function! NextListIdx(lidx) + if a:lidx >= 0 + let llen = len(g:cbTags) + let lidx = (a:lidx + 1)%llen + endif + return lidx +endfunction + +" GetNextList(word) {{{2 +" return the next tag word (from a:word) in the list +function! GetNextList(word) + if a:word == 'tag' + return g:cbTags[0][0] + endif + let liti = WhereInLists(a:word) + if liti[1] == -1 + return "" + endif + let liti[0] = NextListIdx(liti[0]) + let nextword = g:cbTags[liti[0]][0] + return nextword +endfunction + +" SetNextList() {{{2 +" set the current tag to the first tag in the next list +" this is circular, the last list will roll to the first list +function! SetNextList() + let oldtag = GetTag() + let newtag = GetNextList(oldtag) + if newtag == "" + return + endif + let sub = "normal!ci[".newtag + exec sub +endfunction +" vim600: set foldlevel=0 foldmethod=marker: diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_clock.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_clock.vim new file mode 100644 index 0000000..fe16968 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_clock.vim @@ -0,0 +1,139 @@ +"###################################################################### +"# VimOutliner Clock +"# Copyright (C) 2011 by Daniel Carl +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### +" Shortlog{{{1 +" +" This plugin of vimoutliner allow the simple tracking of times and the +" calculation of them in seconds, minutes, hours or days +" Exmaple : +" May -> 64.75 h +" Working time week 51 -> 46.00 h +" Working time week 52 -> 18.75 h +" 2010-05-03 [08:00:00 -- 17:45:00] -> 9.75 h +" 2010-05-04 [09:00:00 -- 18:00:00] -> 9.00 h +" +" TODO: Use better date calculation to track also time around 00:00 +" [23:00:00 -- 03:00:00] that will at the time lead to negative +" hours. +" TODO: change the clocking format so that times over several days could +" be calculated - [2010-05-03 08:00:00 -- 2010-05-23 26:30:45] or +" a shorter dateformat - this seems to need a more complex +" datehandling +" TODO: write a helppage for the vimoutliner that describes the votd_clock +" TODO: allow the user to select his own dateformat +"}}}1 +" ClockStart(space) {{{1 +" Insert a space, then the datetime. +function! ClockStart(space) + let @x = "" + if a:space == 1 + let @x = " " + endif + let @x = @x . strftime("%Y-%m-%d [%T -- %T] ->") + normal! "xp +endfunction +"}}}1 +" ClockStop() {{{1 +" Insert a space, then the datetime. +function! ClockStop() + if match(getline("."), "\\[.* -- .*\\]\\s*-\>") != -1 + call setline(".",substitute(getline(".")," -- .*]\\s*-\>"," -- ".strftime("%T] ->"),"")) + endif +endfunction +"}}}1 +" CalculateSeconds(str) {{{1 +" Calculates the seconds between the start and the end time. +function! CalculateSeconds(str) + let l:parts = split(a:str,"\ --\ ") + let l:startparts = split(l:parts[0],":") + let l:endparts = split(l:parts[1],":") + + let l:seconds = (str2nr(l:endparts[2]) - str2nr(l:startparts[2])) + let l:seconds = (str2nr(l:endparts[1]) - str2nr(l:startparts[1])) * 60 + l:seconds + let l:seconds = (str2nr(l:endparts[0]) - str2nr(l:startparts[0])) * 3600 + l:seconds + return l:seconds +endfunction +" }}}1 +" CalculateDuration() {{{1 +" insert date time +function! CalculateDuration(line) + let l:seconds=0 + let l:count=0 + let l:i = 1 + while Ind(a:line) < Ind(a:line+l:i) + if (Ind(a:line)+1) == (Ind(a:line+l:i)) + let l:childseconds = CalculateDuration(a:line+l:i) + if l:childseconds >= 0 + let l:seconds = l:seconds + l:childseconds + let l:count = l:count+1 + endif + endif + let l:i = l:i+1 + endwhile + + " if no childs found calculate the seconds for the line + let l:lineString = getline(a:line) + if match(l:lineString,"\\s*-\>") != -1 + let l:times = matchstr(l:lineString,"\\[.* -- .*\\]\\s*-\>") + if l:times != "" + " calculate the real time difference + let l:seconds = CalculateSeconds(substitute(l:times,"\\[\\(.*\\)\\]","\\1","")) + endif + " don't add summarized time to text lines + if match(l:lineString,"^\t*[;:<>]") == -1 + if match(l:lineString," -\> [0-9 .]*s") != -1 + call setline(a:line,substitute(l:lineString," -\>.*s"," -> ".l:seconds." s","")) + elseif match(getline(a:line)," -\> [0-9 .]*m") != -1 + call setline(a:line,substitute(l:lineString," -\>.*m"," -> ".printf("%.2f",l:seconds/60.0)." m","")) + elseif match(getline(a:line)," -\> [0-9 .]*d") != -1 + call setline(a:line,substitute(l:lineString," -\>.*"," -> ".printf("%.2f",(l:seconds/86400.0))." d","")) + else + call setline(a:line,substitute(l:lineString," -\>.*"," -> ".printf("%.2f",(l:seconds/3600.0))." h","")) + endif + endif + " else + " return -1 + endif + return l:seconds +endf +"}}}1 +" FindRootParent(line) {{{1 +" returns the line number of the root parent for any child +function! FindRootParent(line) + if Ind(a:line) == 0 + return (a:line) + endif + let l:i = a:line + while l:i > 1 && Ind(l:i) > 0 + let l:i = l:i - 1 + endwhile + return l:i +endf +"}}}1 +" UpdateTimes() {{{1 +" initiates the update of all times in the tree where the cursur is located +function! UpdateTimes() + call CalculateDuration(FindRootParent(line("."))) +endf +"}}}1 +" Mappings {{{1 +nmap cs $:call ClockStart(1) +imap cs ~x:call ClockStart(0)a +nmap cS $:call ClockStop():call UpdateTimes() +imap cS ~x:call ClockStop():call UpdateTimes()i +nmap cu $:call UpdateTimes() +"}}}1 +" The End +" vim600: set foldmethod=marker foldlevel=0: diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_format.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_format.vim new file mode 100755 index 0000000..a59fb33 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_format.vim @@ -0,0 +1,157 @@ +"###################################################################### +"# VimOutliner Format plugin +"# Copyright (C) 2011 by Jostein Berntsen +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### +" Documentation{{{1 +" +" This script inserts bullets, dashes, and arrows in front of lines, including +" VO body text. To insert markers for several lines, select the lines with V +" and execute the mapping. Indents will be kept as they are. +" You can also use the MakeText function to make body text from headers or +" lists. +" +" There are also functions for +" 1) Aligning text in a paragraph to a level 1 header +" 2) Insert checkboxes for all headings in a paragraph +" 3) Indent text in a paragraph/branch to the right +" 4) Indent text in a paragraph/branch to the left +" +"}}}1 +" Load guard for functions {{{1 +if exists("g:loaded_votl_format") || &cp + finish +endif +let g:loaded_votl_format= 1 +let s:keepcpo = &cpo +set cpo&vim + +" Mappings {{{1 + +""" Command mappings +" +" Insert bullets on selected text +map :call InsertBullet() +" Insert dashes on selected text +map :call InsertDash() +" Insert arrows on selected text +map :call InsertArrow() +" Insert colons before selected text +map :call MakeText() +" Align text in a paragraph and indent 1 level +map V}k:leV}> +" Insert checkboxes for text lines in a paragraph +map V}k,,cb +" Indent text in a paragraph 1 level to the right and keep indentation +map :call VOindentright() +" Indent text in a paragraph 1 level to the level and keep indentation +map :call VOindentleft() + +"}}}1 +" InsertBullet() {{{1 +" Insert bullets on selected text. + +function! InsertBullet() + if match(getline("."),"^[\t]*:") != -1 + let @x = ": * " + normal! ^"xPex + else + let @x = "* " + normal! ^"xP + endif +endfunction + +"}}}1 +" InsertDash() {{{1 +" Insert dashes on selected text. + +function! InsertDash() + if match(getline("."),"^[\t]*:") != -1 + let @x = ": - " + normal! ^"xPex + else + let @x = "- " + normal! ^"xP + endif +endfunction + +"}}}1 +" InsertArrow() {{{1 +" Insert arrows on selected text. + +function! InsertArrow() + if match(getline("."),"^[\t]*:") != -1 + let @x = ": --> " + normal! ^"xPex + else + let @x = "--> " + normal! ^"xP + endif +endfunction + +"}}}1 +" MakeText() {{{1 +" Make selected lines body text. + +function! MakeText() + let @x = ":" + normal! ^"xP +endfunction + +"}}}1 +" VOindentright() {{{1 +" Indent branch 1 level to the right. + +function! VOindentright() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! >> + let get_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',get_cursor) + set foldlevel=3 + else + normal! >> + endif +endfunction + + +"}}}1 +" VOindentleft() {{{1 +" Indent branch 1 level to the left. + +function! VOindentleft() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! << + let get_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',get_cursor) + set foldlevel=3 + else + normal! << + endif +endfunction + +"}}}1 +" The End +" vim600: set foldmethod=marker foldlevel=0: + + + diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_gtd.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_gtd.vim new file mode 100644 index 0000000..acdef8b --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_gtd.vim @@ -0,0 +1,219 @@ +"###################################################################### +"# VimOutliner GTD +"# Copyright (C) 2003 by Noel Henson noel@noels-lab.com +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### + +" InsertElem() {{{1 +" Insert a elem without disturbing the current folding. +function! InsertElem(elem) + let @x = a:elem + normal! ^"xP +endfunction +"}}}1 + +" DeleteCheckbox() {{{1 +" Delete a checkbox with all its marks (team/completion) +" if one exists +function! DeleteCheckbox() + :-1/\[[X_?-]\%(,[<>=] [^]]*\)\?\] \%(\d*%\)\?/s/// +endfunction +"}}}1 + +let g:reOutline = "^\t\+\[<>:;|\]" +let g:reBox = "[\[X_?-\]" +let g:reTeam = ",\[<>=\] \[^]\]*" +let g:rePercent = "\\d*% " + +" Safe Insert *Box() {{{1 +" Insert a element at the beginning of a header without disturbing the +" current folding only if there is no element already. +function! InsertSwitch(elem) + if match(getline("."),g:reOutline) != -1 + return + endif +" if match(getline("."),"[".a:elem."\\%(".g:reTeam."\\)\\?"."] ") != -1 +" return +" endif + if match(getline("."),g:reBox."\\%(".g:reTeam."\\)\\?"."] ") != -1 + substitute/\[./\="[".a:elem/ + else + call InsertElem("[".a:elem."] ") + endif +endfunction +"}}}1 + +" Safe Add Team Indicator() {{{1 +" Insert a work with("="), for (">"), waiting for ("<") +" in a checkbox (created if needed) at the beginning of a header +" without disturbing the current folding. +function! SafeAddTeam(elem) + if match(getline("."),g:reOutline) != -1 + return + endif + if match(getline("."),g:reBox.g:reTeam."] ") != -1 + return + endif + if match(getline("."),g:reBox."] ") != -1 + substitute/\[[X_?-]/\=submatch(0).",".a:elem." "/ + else + call InsertElem("[_".",".a:elem." "."] ") + endif +endfunction +"}}}1 + +" Safe InsertCheckBoxPercent() {{{1 +" Insert a checkbox and % sign at the beginning of a header without disturbing +" the current folding +function! SafeAddPercent() +" if Ind(line(".")+1) <= Ind(line(".")) +" return +" endif + if match(getline("."),g:reOutline) != -1 + return + endif + if match(getline("."),g:reBox."\\%(".g:reTeam."\\)\\?"."] ".g:rePercent) != -1 + return + endif + if match(getline("."),g:reBox."\\%(".g:reTeam."\\)\\?"."] ") != -1 + substitute/\[[^]]\+\] /&% / + else + call InsertElem("[_] % ") + endif +endfunction +"}}}1 + +" Ind(line) {{{1 +" Return the index of the line. +" Remove it when using the new version of VO +function! Ind(line) + return indent(a:line) / &tabstop +endf +"}}}1 + +" FindRootParent(line) {{{1 +" returns the line number of the root parent for any child +function! FindRootParent(line) + let l:i = a:line + while l:i > 1 && Ind(l:i) > 0 + let l:i -= 1 + endwhile + return l:i +endf +"}}}1 + +" NewHMD(line) {{{1 +" (How Many Done) +" Calculates proportion of already done work in the subtree +function! NewHMD(line) + let l:done = 0 " checkboxes + let l:count = 0 " number of elems : for % + let l:i = 1 " line counting + let l:proportion = 0 " % : for checkboxes (<100 or 100 ?) and % + let l:lineindent = Ind(a:line) + + " look recursively + + while Ind(a:line+l:i) > l:lineindent + if Ind(a:line+l:i) == l:lineindent + 1 + let l:childdoneness = NewHMD(a:line+l:i) + if l:childdoneness >= 0 + let l:done += l:childdoneness + let l:count += 1 + endif +" echomsg "->".a:line."/".(a:line+l:i)."/ [".l:childdoneness."]-[".l:count."]" + else +" echomsg "(skip) ->".a:line."/".(a:line+l:i) + endif + let l:i += 1 + endwhile + + " update % + + if l:count > 0 +" echomsg "->".a:line." proportion ".l:proportion + let l:proportion = ((l:done * 100)/l:count)/100 + endif + call setline(a:line,substitute(getline(a:line)," [0-9]*%"," ".l:proportion."%","")) + + " + " update checkboxes + " + + " everything under is done, toggle + if l:proportion == 100 +" echomsg "->".a:line." proportion 100." + call setline(a:line,substitute(getline(a:line),"[.","[X","")) + return 100 + endif + + if l:proportion == 0 && l:count == 0 + " done or skipped + if match(getline(a:line),"\[[X-][\],]") != -1 +" echomsg "->".a:line." proportion is X or -." + return 100 + endif + + " not done or questionnable + if match(getline(a:line),"\[[_\?][\],]") != -1 +" echomsg "->".a:line." proportion is _ or ?." + return 0 + endif + + " unknown status for line +" echomsg "->".a:line." proportion is unknown." + return -1 + endif + + " we have not done tasks, undo 'mark as done' + if match(getline(a:line),"\[[X][\],]") != -1 + call setline(a:line,substitute(getline(a:line),"[.","[_","")) + endif +" echomsg "->".a:line." proportion is revert?. [".l:proportion."] / [".l:count."]" + return l:proportion +endf +"}}}1 + +" mappings {{{1 +" gtd addings + " work alone +noremap cb :call InsertSwitch("_") +noremap cq :call InsertSwitch("?") +noremap cD :call InsertSwitch("-") +noremap cx :call InsertSwitch("X"):call NewHMD(FindRootParent(line("."))) +" noremap cx :call InsertSwitch("X") + " team work +noremap cw :call SafeAddTeam("<") +noremap cf :call SafeAddTeam(">") +noremap c= :call SafeAddTeam("=") +" completion +noremap c% :call SafeAddPercent() + +" forced mapping +noremap gb :call InsertElem("[_] ") +noremap gq :call InsertElem("[?] ") +noremap gD :call InsertElem("[-] ") +noremap gx :call InsertElem("[X] ") +noremap gw :call InsertElem("[_,< ] ") +noremap gf :call InsertElem("[_,> ] ") +noremap g= :call InsertElem("[_,= ] ") +noremap g% :call InsertElem("[_] % ") + +" delete a chechbox +noremap cd :call DeleteCheckbox() + +" calculate the proportion of work done on the subtree +noremap cz :call NewHMD(FindRootParent(line("."))) +"}}}1 + +" vim600: set foldlevel=0 foldmethod=marker: diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.otl b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.otl new file mode 100644 index 0000000..54fe307 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.otl @@ -0,0 +1,56 @@ +VO Math +Syntax + {} contains formalae to compute + {f0;f1} semicolon separates formulae + There is a respective order between the formulae and variables in a heading + {math0;math1;math2} var0=result0 var1=result1 var2=result2 + ordering + Math can come before or after variables + {3+5;3*5} sum=8 product=15 + sum=8 product=15 {3+5;3*5} + name=n name become a named result for passing to a parent + A=n B=n space separates variables + A=n test B=n space separates variables, interspersed words are allowed +Math Examples + Example 1: one-line math {3*5} result=15 + Example 2: one-line floating-point math {3*5.0} result=15.0 + Example 3: Simple math with child variables {A*B+C} result=5.0 + Item 1 A=2 + Item 2 B=2 + Item 3 C=3.0 + Example 4: Automatic summing {bonk} total=6.0 + Item 1 bonk=1 + Item 2 bonk=2 + Item 3 bonk=3.0 + Example 5: Multiple equations {A*B;B*C;C*A;A+B+C} AB=2.0 BC=6.0 CA=3.0 sumABC=6.0 + Item 1 A=1 + Item 2 B=2 + Item 3 C=3.0 + Example 6: Multiple trees {Labor;Materials;Total} Labor=1222.5 Materials=225.0 Total=1447.5 + Project 1 {Labor;Materials;Labor+Materials} Labor=747.5 Materials=110.0 Total=857.5 + Task 1 {Hours*Rate;Materials} Labor=500.0 Materials=100.0 + Hours=10 + Rate=50 + Materials=100 + Task 2 {Hours*Rate;Materials} Labor=247.5 Materials=10.0 + Hours=4.5 + Rate=55 + Materials=10 + Project 2 {Labor;Materials;Labor+Materials} Labor=475.0 Materials=115.0 Total=590.0 + Task 1 {Hours*Rate;Materials} Labor=300.0 Materials=70.0 + Hours=6 + Rate=50 + Materials=70 + Task 2 {Hours*Rate;Materials} Labor=175.0 Materials=45.0 + Hours=3.5 + Rate=50 + Materials=45 + Example 7: Reversal of results and maths AB=2.0 BC=6.0 CA=3.0 sumABC=6.0 {A*B;B*C;C*A;A+B+C} + Item 1 A=1 + Item 2 B=2 + Item 3 C=3.0 + Example 8: Scientific notation: {10000.0*100000} result=1.0e9 + Example 9: Trigonometry: {sin(pi/4)} theta=0.707107 + pi=3.1415926 + Example 10: Base conversion: {printf("0x%x",65)} hex='0x41' + Example 11: Vim internal state: {&ts;&foldlevel} tabstop=4 foldlevel=99999 diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.vim new file mode 100644 index 0000000..5c09db1 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_math.vim @@ -0,0 +1,286 @@ +"###################################################################### +"# VimOutliner Outline Math +"# Copyright (C) 2014 by Noel Henson noelwhenson@gmail.com +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### + +" Naming Conventions ################################################## {{{1 +" lnum: line number +" line: string from a line +" vars: dictionary of variables, key:value pairs +" +" Common Functions #################################################### {{{1 +" These functions have broader application scope than those specific to +" performing math on outline trees. Perhaps even adding math to VO tables. +" + +" MyLineage(lnum) {{{2 +" return a list of ancestors in order of youngest-first +" eg: +" 9 A +" 10 B +" 11 C +" 12 D +" MyLineage(12) +" [11,10,9] +function! MyLineage(lnum) + let lineage = [] + let lnum = a:lnum + let indent = Ind(lnum) + if indent == 0 + return lineage + endif + let parentIndent = indent - 1 + while (parentIndent >= 0) && (lnum >= 0) + while (indent > parentIndent) && (lnum >= 0) + let lnum -= 1 + let indent = Ind(lnum) + endwhile + let lineage += [lnum] + let parentIndent -= 1 + endwhile + return lineage +endfunction + +" MyChildren(lnum) {{{2 +" return a list of immediate children from the specificed line +function! MyChildren(lnum) + let children = [] + let parentInd = Ind(a:lnum) + let childInd = parentInd + 1 + let last = line("$") + let lnum = a:lnum + 1 + let lnumInd = Ind(lnum) + while (lnum <= last) && (parentInd < lnumInd) + if lnumInd == childInd + let children += [lnum] + endif + let lnum += 1 + let lnumInd = Ind(lnum) + endwhile + return children +endfunction + +" RootParents() {{{2 +" return a list of all root nodes (indent level 0) +function! RootParents() + let parents = [] + let lnum = 1 + let lines = line("$") + while lnum <= lines + let ind = Ind(lnum) + if ind == 0 + let parents += [lnum] + endif + let lnum += 1 + endwhile + return parents +endfunction + +" FindMath(string) {{{2 +" location of first character of match, -1 if not +" notation: ...{...}...=number... +" function! FindMath(string) +" return match(a:string,'{.*}.*=-\?[0-9]\+\(.[0-9]\+\)\+\([eE][-+]\?[0-9]\+\)\?') +" endfunction +" the below is faster! +" function! FindMath(string) +" return match(a:string,'{.*}.*=-\?[0-9]') +" endfunction +" the below is even faster +" and allows for formulae to be placed at the end of a heading +function! FindMath(string) + if match(a:string,'=') != -1 + return match(a:string,'{.*}') + else + return -1 + endif +endfunction + +" GetMathFromString(string) {{{2 +" returns a list of formulae in a string, in the order they were listed +" returns an empty list if none +" notation: {formula} or {formula1;formula2;...;formulan} +function! GetMathFromString(string) + let mstart = FindMath(a:string) + if mstart == -1 + return [] + endif + let mstart += 1 + let mend = match(a:string,'}',mstart) + if mend == -1 + return [] + endif + let mend -= 1 + return split(a:string[mstart : mend],';') +endfunction + +" MarkValues(string) {{{2 +" mark Values in a string for replacement by formula results +" turns each number into '= voMathResult' +function! MarkValues(string) + return substitute(a:string,'=-\?[0-9]\+\(.[0-9]\+\)\?\([eE][-+]\?[0-9]\+\)\?','=voMathResult','g') +endfunction + +" GetVarsFromString(string,vars) {{{2 +" add key:value pairs from a string to the passed dictionary +" create new entries if key does not exist +" add values to existing entries +" vars is a dictionary of key:value pairs +" notation: name=number +function! GetVarsFromString(string,vars) + " quick return if no potential variables + if match(a:string,'=') == -1 + return + endif + let tokens = split(a:string) + for token in tokens + if match(token,'=') == -1 + continue + endif + let [key,value] = split(token,"=") + " read values are cast to floats to prevent + " auto-casting to integers in the first case + " and strings in the second + if has_key(a:vars,key) + let a:vars[key] += str2float(value) + else + let a:vars[key] = str2float(value) + endif + endfor +endfunction + +" ReplaceVars(formula,vars) {{{2 +" replace variables with their values from the supplied dictionary +" vars is a dictionary of key:value pairs +" key:value pairs are first sorted by key length, longest-first +" this prevents name collisions when similar key names are used like: +" Total and Totals -or- X1 and X12 +function! ReplaceVars(formula,vars) + let formula = a:formula + let vars = [] + for [key,val] in items(a:vars) + let vars += [[len(key),key,val]] + endfor + let vars = reverse(sort(vars)) + for [len,key,val] in vars + let formula = substitute(formula,key,string(val),"g") + endfor + return formula +endfunction + +" ComputeString(string,vars) {{{2 +" compute a string using its math and a dictionary of variables +" return the computed, modified string +" string is a string containing math and result variable names +" vars is a dictionary of key:value pairs used in the computation +function! ComputeString(string,vars) + let string = a:string + let maths = GetMathFromString(string) + if len(maths) + let string = MarkValues(string) + for math in maths + let math = ReplaceVars(math,a:vars) + let result = string(eval(math)) + let string = substitute(string,'voMathResult',result,"") + endfor + endif + return string +endfunction + +" Math Functions on Outlines ########################################## {{{1 + +" MyChildrensVars(lnum) {{{2 +" return a dictionary of variable from immediate children +function! MyChildrensVars(lnum) + let children = MyChildren(a:lnum) + let vars = {} + for child in children + call GetVarsFromString(getline(child),vars) + endfor + return vars +endfunction + +" ComputeLine(lnum) {{{2 +" compute a line's maths using variables from it's children +" replace the line with the newly computed line +function! ComputeLine(lnum) + let vars = MyChildrensVars(a:lnum) + let line = ComputeString(getline(a:lnum),vars) + call setline(a:lnum,line) +endfunction + +" ComputeUp(lnum) {{{2 +" compute 'up' a tree towards level 1 +" the line (lnum) itself is computed first +" this is intended to be a fast compute method to update a branch of nodes +" it assumes that all other calculations in a tree are correct +function! ComputeUp(lnum) + call ComputeLine(a:lnum) + let lineage = MyLineage(a:lnum) + if len(lineage) + for lnum in lineage + call ComputeLine(lnum) + endfor + endif +endfunction + +" ComputeDown(lnum) {{{2 +" compute 'down' a tree from the current node +" the line (lnum) itself is computed last +function! ComputeDown(lnum) + let children = MyChildren(a:lnum) + if len(children) + for lnum in children + call ComputeDown(lnum) + endfor + endif + call ComputeLine(a:lnum) +endfunction + +" ComputeTree(lnum) {{{2 +" compute down an entire tree +function! ComputeTree(lnum) + let parents = MyLineage(a:lnum) + if len(parents) + let topparent = parents[-1] + else + let topparent = a:lnum + endif + call ComputeDown(topparent) +endfunction + +" ComputeDocument() {{{2 +" compute down all trees + +function! ComputeDocument(lnum) + let parents = RootParents() + for parent in parents + call ComputeDown(parent) + endfor +endfunction + +" Concealings {{{1 +" BadWord is a very old VO region that is no longer used. +" It can be used now for plugins :) +" This should probably be fixed at some point in the future +syntax match BadWord "{.\+}" conceal transparent cchar=µ +set conceallevel=1 + +" mappings {{{1 + +map == :call ComputeUp(line(".")) +map =t :call ComputeTree(line(".")) +map =d :call ComputeDocument() +map =h :set conceallevel=1 +map =H :set conceallevel=0 diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_newhoist.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_newhoist.vim new file mode 100644 index 0000000..e2ecd64 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_newhoist.vim @@ -0,0 +1,456 @@ +"###################################################################### +"# VimOutliner Hoisting +"# Copyright (C) 2003 by Noel Henson noel@noels-lab.com +"# The file is currently an experimental part of Vim Outliner. +"# +"# This program is free software; you can redistribute it and/or modify +"# it under the terms of the GNU General Public License as published by +"# the Free Software Foundation; either version 2 of the License, or +"# (at your option) any later version. +"# +"# This program is distributed in the hope that it will be useful, +"# but WITHOUT ANY WARRANTY; without even the implied warranty of +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"# GNU General Public License for more details. +"###################################################################### + +" Load the plugin {{{1 +if exists("g:did_vo_hoist") + "finish +endif +if !exists("g:hoistParanoia") + let g:hoistParanoia=0 +endif +if !exists('hlevel') + let hlevel = 20 +endif +let g:did_vo_hoist = 1 +" mappings {{{1 +map hh :call Hoist(line(".")) +map hd :call DeHoist() +map hD :call DeHoistAll() +"}}}1 +" syntax {{{1 +" Hoisted {{{2 +"syntax match Invis +^\~\zs.*$+ containedin=ALL conceal cchar=~ +""hi Invis guifg=bg ctermfg=bg +""hi Invis guifg=bg +"hi link Invis Conceal +"}}}2 +"}}}1 +" MyFoldText() {{{1 +" Create string used for folded text blocks +function! MyFoldText() + let l:MySpaces = MakeSpaces(&sw) + let l:line = getline(v:foldstart) + let l:bodyTextFlag=0 + if l:line =~'^\~' + let l:line = '~'.repeat(' ', winwidth(0)-1) + elseif l:line =~ "^\t* \\S" || l:line =~ "^\t*\:" + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[TEXT]" + elseif l:line =~ "^\t*\;" + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[TEXT BLOCK]" + elseif l:line =~ "^\t*\> " + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER]" + elseif l:line =~ "^\t*\>" + let l:ls = stridx(l:line,">") + let l:le = stridx(l:line," ") + if l:le == -1 + let l:l = strpart(l:line, l:ls+1) + else + let l:l = strpart(l:line, l:ls+1, l:le-l:ls-1) + endif + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER ".l:l."]" + elseif l:line =~ "^\t*\< " + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER BLOCK]" + elseif l:line =~ "^\t*\<" + let l:ls = stridx(l:line,"<") + let l:le = stridx(l:line," ") + if l:le == -1 + let l:l = strpart(l:line, l:ls+1) + else + let l:l = strpart(l:line, l:ls+1, l:le-l:ls-1) + endif + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[USER BLOCK ".l:l."]" + elseif l:line =~ "^\t*\|" + let l:bodyTextFlag=1 + let l:MySpaces = MakeSpaces(&sw * (v:foldlevel-1)) + let l:line = l:MySpaces."[TABLE]" + endif + let l:sub = substitute(l:line,'\t',l:MySpaces,'g') + let l:len = strlen(l:sub) + let l:sub = l:sub . " " . MakeDashes(58 - l:len) + let frange = (v:foldend + l:bodyTextFlag)- v:foldstart + let l:sub = l:sub . " (" . frange + if frange == 1 + let l:sub = l:sub . " line)" + else + let l:sub = l:sub . " lines)" + endif + return l:sub.repeat(' ', winwidth(0)-len(l:sub)) +endfunction +"}}}1 +" New Fold Function (will be put into vo_base later {{{1 +function! MyHoistableFoldLevel(line) + let l:myindent = Ind(a:line) + let l:nextindent = Ind(a:line+1) + + if HoistFold(a:line) + " if (a:line == 1) + " return g:hlevel + " elseif (HoistFold(a:line-1) == 0) + " return ">".0 + " else + " return g:hlevel + " endif + return g:hlevel + + elseif BodyText(a:line) + if (BodyText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (BodyText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedBodyText(a:line) + if (PreformattedBodyText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedBodyText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedTable(a:line) + if (PreformattedTable(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedTable(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedUserText(a:line) + if (PreformattedUserText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedUserTextSpace(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif PreformattedUserTextLabeled(a:line) + if (PreformattedUserTextLabeled(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (PreformattedUserText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif UserText(a:line) + if (UserText(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (UserTextSpace(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + elseif UserTextLabeled(a:line) + if (UserTextLabeled(a:line-1) == 0) + return '>'.(l:myindent+1) + endif + if (UserText(a:line+1) == 0) + return '<'.(l:myindent+1) + endif + return (l:myindent+1) + else + if l:myindent < l:nextindent + return '>'.(l:myindent+1) + endif + if l:myindent > l:nextindent + return (l:myindent) + endif + return l:myindent + endif +endfunction +set foldexpr=MyHoistableFoldLevel(v:lnum) +"}}}2 +"}}}1 +" Functions {{{1 +" RemoveTabs(line,tabs) {{{2 +" remove specified number of tabs from the begining of line +function! RemoveTabs(start,end,tabs) + if a:tabs > 0 + let l:doit = "silent ".a:start.",".a:end."s/^\\(\\t\\)\\{".a:tabs."}/" + exe l:doit + endif +endfunction +"}}}2 +" IsParent(line) {{{2 +" Return 1 if this line is a parent +function! IsParent(line) + return (Ind(a:line)+1) == Ind(a:line+1) +endfunction +"}}}2 +" FindParent(line) {{{2 +" Return line if parent, parent line if not +function! FindParent(line) + if IsParent(a:line) + return a:line + else + let l:parentindent = Ind(a:line)-1 + let l:searchline = a:line + while (Ind(l:searchline) != l:parentindent) && (l:searchline > 0) + let l:searchline = l:searchline-1 + endwhile + return l:searchline + endif +endfunction +"}}}2 +" HoistFold() {{{2 +" Return a flag indicating that there is a valid hoist +function! HoistFold(line) + if getline(a:line) =~ '^\~' + return 1 + else + return 0 + endif +endfunction +"}}}2 +" Hoisted() {{{2 +" Return a flag indicating that there is a valid hoist +function! Hoisted() + if getline(1) =~ '^\~' + return 1 + else + return 0 + endif +endfunction +"}}}2 +" FindTopHoist(line) {{{2 +" Return line number of the nearest (last line) top hoist tag +function! FindTopHoist(line) + let l:line = a:line + while (match(getline(l:line),"^\\~") == -1) && (l:line > 0) + let l:line -= 1 + endwhile + return l:line +endfunction +"}}}2 +" FindBottomHoist(line) {{{2 +" Return line number of the nearest (last line) top hoist tag +function! FindBottomHoist(line) + let l:line = a:line + let l:lastline = line('$') + while getline(l:line) !~ "^\\~" && (l:line > 0) && l:line <= l:lastline + let l:line += 1 + endwhile + return l:line +endfunction +"}}}2 +" FindLastChild(line) {{{2 +" Return the line number of the last decendent of parent line +function! FindLastChild(line) + let l:parentindent = Ind(a:line) + let l:searchline = a:line+1 + while Ind(l:searchline) > l:parentindent + let l:searchline = l:searchline+1 + endwhile + return l:searchline-1 +endfunction +"}}}2 +" GetHoistedIndent(line) {{{2 +" line is the line number containing the indent +" Returns the original indent of the hoisted region +function! GetHoistedIndent(line) + return str2nr(strpart(getline(a:line),1,2)) +endfunction +"}}}2 +" HoistTagBefore(line,indent) {{{2 +function! HoistTagBefore(line,indent) + let l:doit = "silent 1,".(a:line-1)."s/^/\\~".a:indent." /" + exe l:doit + "call setline(1, map(getline(1,a:line-1), '"~".a:indent.v:val')) +endfunction +"}}}2 +" HoistDeTagBefore(line) {{{2 +function! HoistDeTagBefore(line) + let l:doit = "silent 1,".a:line."s/^\\~\\d* //" + exe l:doit +endfunction +"}}}2 +" HoistTagAfter(line) {{{2 +function! HoistTagAfter(line) + if a:line > line('$') + return + endif + let l:doit = "silent ".a:line.",$s/^/\\~/" + exe l:doit +endfunction +"}}}2 +" HoistDeTagAfter(line) {{{2 +function! HoistDeTagAfter(line) + if a:line > line('$') + return + endif + let l:doit = "silent ".a:line.",$s/^\\~//" + exe l:doit +endfunction +"}}}2 +" HoistWrite(file) {{{2 +" Write the clean file if hoisted +function! HoistWrite(file,...) range + "let lines = getline(1,line('$')) + let saved = 0 + mkview + call DeHoistAll() + if v:cmdbang + let bang = '!' + else + let bang = '' + endif + try + if a:0 + echom a:firstline.','.a:lastline."w".bang.fnameescape(v:cmdarg).' '.a:file + exe a:firstline.','.a:lastline."w".bang.fnameescape(v:cmdarg).' '.a:file + else + exe "w".bang.fnameescape(v:cmdarg).' '.a:file + endif + let saved = 1 + catch + echohl ErrorMsg + echom substitute(v:exception,'^Vim(.\{-}):','','') + echohl None + endtry + "call setline(1,lines) + silent earlier + silent loadview + if saved + silent setlocal nomodified + endif +endfunction "HoistWrite +" Hoist(line) {{{2 +" Write the offspring of a parent to a new file, open it and remove the +" leading tabs. +function! Hoist(line) + let l:parent = FindParent(a:line) + if l:parent == 0 + return + endif + "call cursor(l:parent,1) + "let l:firstline = l:parent+1 + let l:firstline = l:parent + let l:childindent = Ind(l:firstline) + let l:lastline = FindLastChild(l:parent) + setlocal foldlevel=20 + call HoistTagBefore(l:firstline,l:childindent) + call HoistTagAfter(l:lastline+1) +" call RemoveTabs(l:firstline,l:lastline,l:childindent) + call cursor(l:firstline,1) + setlocal foldlevel=19 + augroup VO_HOIST + au! + au CursorMoved,CursorMovedI + \ if getline('.') =~ '^\~\d* ' | + \ call HoistKeepCursor(1) | + \ elseif getline('.') =~ '^\~' | + \ call HoistKeepCursor(0) | + \ endif + "au BufWriteCmd call HoistWrite(fnameescape(expand(""))) + "au FileWriteCmd '[,']call HoistWrite(fnameescape(expand("")), 1) + augroup END + if exists('+conceallevel') + syntax match Invis +^\~.*$+ conceal cchar=~ + hi link Invis Conceal + setlocal conceallevel=2 + else + syntax match Invis +^\~.*$+ containedin=ALL + let i = 1 + while synIDtrans(i) != 0 + if synIDattr(i, 'name') == 'Normal' + if synIDattr(i, 'bg') >= 0 + " bg is set + hi Invis guifg=bg ctermfg=bg + else + hi Invis guifg=NONE ctermfg=NONE + endif + break + endif + let i += 1 + endwhile + endif +endfunction +" }}}2 +" HoistKeepCursor(top) {{{2 +" Keep cursor out of non-hoisted area. +function! HoistKeepCursor( top ) + if a:top + while getline('.') =~ '^\~\d* ' + normal! j + endwhile + else + while getline('.') =~ '^\~' + normal! k + endwhile + endif +endfunction "HoistKeepCursor }}}2 +" MakeTabs(n) {{{2 +" return a string of n tabs +function! MakeTabs(n) + let l:tabs = "" + let l:n = a:n + while l:n > 0 + let l:tabs = l:tabs."\t" + let l:n -= 1 + endwhile + return l:tabs +endfunction +"}}}2 +"}}}2 +" DeHoist() {{{2 +" Write the offspring of a parent to a new file, open it and remove the +" leading tabs. +function! DeHoist() + if !Hoisted() + return + endif + let l:line = line(".") + let l:top = FindTopHoist(l:line) + let l:bottom = FindBottomHoist(l:line) + echom 1 + let l:indent = GetHoistedIndent(l:top) +" let l:tabs = MakeTabs(l:indent) +" let l:doit = "silent ".(l:top+1).",".(l:bottom-1)."s/^/".l:tabs."/" +" exe l:doit + call HoistDeTagBefore(l:top) + call HoistDeTagAfter(l:bottom) + if !Hoisted() + augroup VO_HOIST + au! + augroup! VO_HOIST + augroup END + endif + call cursor(l:line,l:indent) +endfunction +"}}}2 +" DeHoistAll() {{{2 +" Write the offspring of a parent to a new file, open it and remove the +" leading tabs. +function! DeHoistAll() + while Hoisted() + call DeHoist() + endwhile +endfunction +"}}}2 +"}}}1 +" vim600: set foldlevel=0 foldmethod=marker: diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_smart_paste.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_smart_paste.vim new file mode 100644 index 0000000..6aa0c45 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_smart_paste.vim @@ -0,0 +1,117 @@ +" Here is a small script that remaps the p and P normal commands such that VO +" will do what one would expect when pasting cut/copied nodes into another +" section of an outline. It will adjust the indents and not paste into the +" middle of a branch. +" Added 2011-03-01(JB): This script will now also copy an outline correctly by +" using \\y, copy to the register with \\r, cut an outline by using \\d, and +" paste from the register using \\b. +" http://www.lists.vimoutliner.org/pipermail/vimoutliner/2008-October/002366.html + +map p :call VOput() +map \\b :call VOputreg() +map \\y :call VOcop() +map \\r :call VOreg() +map \\d :call VOcut() +map P ]P + +if exists('s:loaded') + finish +endif +let s:loaded = 1 + +function! IsParent(line) + if a:line == line("$") + return 0 + elseif Ind(a:line) < Ind(a:line+1) + return 1 + else + return 0 + endif +endfunction + + +function! VOcop() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! yy + let get_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',get_cursor) + else + normal! yy + endif +endfunction + +function! VOreg() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! V"+y + let get_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',get_cursor) + else + normal! V"+y + endif +endfunction + +function! VOcut() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! dd + let get_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',get_cursor) + else + normal! dd + endif +endfunction + +function! VOput() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! ]p + let put_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',put_cursor) + else + normal! ]p + endif +endfunction + + +function! VOputreg() + let thisLine = line(".") + if (foldclosed(thisLine) == -1) && IsParent(thisLine) + normal! zc + let fold_cursor = getpos(".") + normal! "+]p + let put_cursor = getpos(".") + call setpos('.',fold_cursor) + normal! zo + call setpos('.',put_cursor) + else + normal! "+]p + endif +endfunction + + + + + + + + + + diff --git a/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_tags.vim b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_tags.vim new file mode 100644 index 0000000..c5bebde --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/plugin/votl_tags.vim @@ -0,0 +1,246 @@ +" File: plugin/votl_tags.vim +" Version: 1.0 +" Modified: 2011-02-28 +" Description: This plugin provides inter-outline links for vimoutliner. +" Maintainer: Israel Chauca F. +" Manual: The following mappings are added: +" - : Follow a link. +" - : Jump back in the link-history. +" - l : Create a link. +" ============================================================================ + +if v:version < 700 + echom 'VimOutliner: votl_tags.vim requires Vim 7.0 or later.' + finish +endif + +" Create outlines' jump-list. +if !exists('w:vo_jump_list') + let w:vo_jump_list = [] +endif + +" Mappings {{{1 + +" Follow inter-outline link. +noremap VO_FollowLink :call follow_link() +if !hasmapto('VO_FollowLink') + "map VO_FollowLink + map VO_FollowLink +endif + +" Go back to previous outline. +noremap VO_JumpBack :call jump_back() +if !hasmapto('VO_JumpBack') + "map VO_JumpBack + map VO_JumpBack +endif + +" Create a link from a word in normal mode. +noremap VO_CreateLink :call create_link() +if !hasmapto('VO_CreateLink') + silent! map l VO_CreateLink +endif + +" Create a link from a word in insert mode. +inoremap VO_CreateLinkI :call create_link() +if !hasmapto('VO_CreateLinkI') + silent! imap l VO_CreateLinkI +endif + +" Functions {{{1 + +let s:checkboxpat = '\%(\[[^[\]]\+\]\s\+\%(\d*%\d*\s\+\)\?\)\?' + +" Don't re-load functions. +if exists('s:loaded') + finish +endif +let s:loaded = 1 + +" s:get_link() {{{2 +" Get link data. +function! s:get_link(linenr) + " Check if it's a valid link. + let line = getline(a:linenr) + if line =~? '\m^\t*'.s:checkboxpat.'_tag_\w\+\s*$' + " Don't remember where this bit came from, please let me know if you do. + let [_,file,row,col;m0] = matchlist(getline(a:linenr + 1), '\m^\t*'.s:checkboxpat.'\([^:]\+\)\%(:\(\d\+\)\)\?\%(:\(\d\+\)\)\?$') + elseif line =~? '\m^\t*'.s:checkboxpat.'_ilink_\(.\{-}:\s\)\?\s*\S.*$' + let pat = '\m^\t*'.s:checkboxpat.'_ilink_\%([^:\\/]\{-}:\s\)\?\s*\(.\+\)\%(:\(\d\+\)\)\?\%(:\(\d\+\)\)\?$' + let [_,file,row,col;m0] = matchlist(line, pat) + else + return ['',0,0,0] + endif + let is_inner_link = 0 + if file == '%' + let file = expand('%:p') + let is_inner_link = 1 + endif + let row = (row == '' ? 0 : row * 1) + let col = (col == '' ? 0 : col * 1) + + return [file, row, col, is_inner_link] +endfunction + +" s:follow_link() {{{2 +" Follow an interoutline link. +function! s:follow_link() + " Get link data. + let [file, row, col, is_inner_link] = s:get_link(line('.')) + if file == '' + echom 'Vimoutliner: "'.substitute(getline('.'), '\m^\t*'.s:checkboxpat, '', '').'" doesn''t not look like an inter-outline link.' + return + endif + + " Check if file path exists. + let file = s:get_absolute_path(expand('%:h'), file) + let file = fnamemodify(file,':p') + let baseDir = fnamemodify(file,':h') + let dirconfirm = 0 + " Check if directories exists. {{{3 + if glob(baseDir) == '' + if exists('*confirm') + let dirconfirm = confirm('The linked file "'.file.'" and one or more directories do not exist, do you want to create them now?', "&Yes\n&No", '2', 'Question') + else + " Can't ask, asume a yes for answer. + let dirconfirm = 1 + endif + if dirconfirm == 1 + " Create dir(s): + if exists('*mkdir') + call mkdir(baseDir,'p') + elseif executable('mkdir') + call system('`which mkdir` -p '.shellescape(baseDir)) + else + echom 'Vimoutliner: Vim can not create the required directories, please create them yourself.' + return + endif + else + return + endif + endif + " Check if file exists. {{{3 + if glob(file) == '' + if exists('*confirm') && dirconfirm == 0 + let confirm = confirm('The linked file "'.file.'" does not exist, do you want to create it now?', "&Yes\n&No", '2', 'Question') + else + " Can't ask, asume a yes for answer. + let confirm = 1 + endif + if confirm == 1 + call writefile([], file) + else + return + endif + endif + " }}}3 + " Now let's jump to that outline. + try + call s:update_jump_list() + if !is_inner_link + exec "buffer ".bufnr(substitute(file, '\m^'.getcwd().'/','',''), 1) + endif + if row > 0 + call setpos('.',[0,row,col,0]) + endif + setlocal buflisted + catch + " Prevent reporting that the error ocurred inside this function. + echoh ErrorMsg + echom substitute(v:exception,'\m^Vim(.\{-}):','','') + echoh None + endtry + return '' +endfunction +" s:get_absolute_path(baseDir, fileName) {{{2 +" Guess an absolute path +function! s:get_absolute_path(baseDir, fileName) + let baseDir = a:baseDir + if baseDir !~ '/$' + let baseDir = baseDir . '/' + endif + if a:fileName =~ '^/' + let absFileName = a:fileName + else + let absFileName = baseDir . a:fileName + endif + + let absFileName = substitute(absFileName, '\m/\./', '/', 'g') + while absFileName =~ '/\.\./' + absFileName = substitute(absFileName, '\m/[^/]*\.\./', '', '') + endwhile + return absFileName +endfunction +" s:update_jump_list() {{{2 +" Add current outline to list. +function! s:update_jump_list() + call add(w:vo_jump_list, [bufnr('%')] + getpos('.')) +endfunction +" s:remove_buf(buf) {{{2 +" Remove outline from list. +function! s:remove_buf() + if !exists('w:vo_jump_list') || len(w:vo_jump_list) == 0 + return + endif + " Remove last outline. + call remove(w:vo_jump_list, -1) +endfunction +" s:jump_back() {{{2 +" Jump back to the previous outline. +function! s:jump_back() + if len(w:vo_jump_list) == 0 + echom 'This is the first outline.' + return + endif + exec "buffer ".w:vo_jump_list[-1][0] + call setpos('.', w:vo_jump_list[-1][1 : ]) + call s:remove_buf() +endfunction +" s:create_link() {{{2 +" Create an interoutline link with the current keyword under the cursor. +function! s:create_link() + let line = getline('.') + " Create link on a header only + if line =~ '\m^\t\+[^ :;<>|]' + echom 'Vimoutliner: Links have to be on a header.' + return + endif + " Check if the there's is some content in the current line and a current + " link doesn't exists. + if line =~# '\m^\t*'.s:checkboxpat.'_ilink_\%([^:]\{-}:\s\)\?\s*\S\+.*$' + echom 'Vimoutliner: Looks like "'.substitute(line,'^\t*'.s:checkboxpat.'\(\S.*$\)','\1','').'" is already a link.' + return + endif + call inputsave() + let path = input('Linked outline''s path: ', '', 'file') + call inputrestore() + if path == '' + " User canceled. + return '' + endif + let path = matchstr(path, '\m^\t*'.s:checkboxpat.'\zs\S.\{-}\ze\s*$') + "if path !~ '\.otl$' + "" Add extension. + "let path = path.'.otl' + "endif + let tag = '_ilink_' + let [_,indent,checkbox,label;m0] = matchlist(line, '\m^\(\t*\)\('.s:checkboxpat.'\)\%(_ilink_\)\?\s*\(\S\%(.\{-1,}\S\)\?\)\?\s*\%(:\s\)\?\s*$') + "echom indent.'-'.checkbox.'-'.label + if indent == '' + let indent = matchstr(getline(line('.')-1), '\m^\(\t*\)') + endif + if label !~ ':\s*$' + let label = substitute(label, '\m\s*$', ': ', '') + else + let label = substitute(label, '\m:\s*$', ': ', '') + endif + + call setline(line('.'), indent.checkbox.tag.' '.label.path) + echo '' +endfunction +" Autocommands {{{1 +augroup vo_links + au! + au BufWinEnter * if !exists('w:vo_jump_list') | let w:vo_jump_list = [] | endif +augroup END +"{{{1 vim:foldmethod=marker diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl new file mode 100644 index 0000000..f8f5f1a --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl @@ -0,0 +1,17 @@ +"delete trailing white space +:%s/^[ \t][ \t]*\(.*\)$/\1/ +"delete one line from each block of empty lines +:g/^\_$\n\_^..*$/d +"add leading : to body text +:%s/^[^=]..*[^=]$/:&/ +"add leading : to dividers made entirely of equal signs +:%s/^==*$/:&/ +"delete one leading = and space from heading +"delete trailing space and = from heading +"\1 is leading equal signs. \2 is heading. +:%s/^=\(=*\) \(.*\) =\+$/\1\2/ +"indent body text lines (lines starting with ":") +"how to indent body text lines? +"indent headings +"substitute each = with tab +:g/^=/s/=/\t/g diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl.desc b/pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl.desc new file mode 100644 index 0000000..6f8a7f6 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/MediaWiki2otl.desc @@ -0,0 +1,37 @@ +This email has the attachment. + +Hello Vim Outliners, + +I want to migrate some word processor documents to otl.  If you know of a formatter to convert "MediaWiki to otl" or "odt to otl" or "doc to otl" please let me know.  I did not find one. + +I am attempting to write ex script to convert MediaWiki to otl.  This would be useful because LibreOffice Writer can export to MediaWiki format, and then the script would convert it to otl. + +The heading format in MediaWiki is simple; one equal sign for each level in the heading hierarchy e.g.: + += head1 = +body text +== head2 == +body text +=== head3 === +body text + +The above MediaWiki text should convert to otl like this: + +head1 +:body text +head2 +:body text +head3 +:body text + +The attached MediaWiki2otl script converts MediaWiki to otl except for one thing.  I can not figure out how to indent the body text lines (indent lines that start with “:”). Here is the pseudo code: + +if current line has “=” +set count to number of “=” +else   +insert count “\t” + +Can this be done in ex script? i.e. Is there an ex command that can set a variable (or register) and an ex command to read that variable in the following lines? + +Thank you, +wolfv diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING new file mode 100644 index 0000000..0e7003c --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING @@ -0,0 +1,118 @@ +The Litt Perl Development Tools License +Version 1.0, 3/14/2003 +--------------------------------------- + +The Litt Perl Development Tools License (LPDTL) +consists of the GNU GPL plus an exception, plus an +exception to that exception. + +This program is free software; you can +redistribute it and/or modify it under the terms +of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it +will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General +Public License along with this software; see the +file COPYING.GPL. If not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite +330, Boston, MA 02111-1307 USA. Other locations +for the GNU General Public License include: + + http://www.troubleshooters.com/licenses/LPDTL/COPYING.GPL + +and + + http://www.gnu.org/licenses/gpl.txt + + +THE EXCEPTION + +As a special exception, the author of this Perl +Development Tool gives permission for additional +uses of the text contained in this Perl +Development Tool. + +The exception is that, if you reference the LPDTL +licensed software, by use of a Perl "use" or +"require" statement, from other files, this does +not by itself cause the files referencing this +Perl Development Tool to be covered by the GNU +General Public License. Your use of the +referencing files is in no way restricted on +account of their referencing the code in this Perl +Development Tool. + +Likewise, if you link the LPDTL licensed software +with other files to produce an executable, this +does not by itself cause the resulting executable +to be covered by the GNU General Public License. +Your use of that executable is in no way +restricted on account of linking the LPDTL +licensed software's code into it. + + +EXCEPTION LIMITATIONS + +This exception does not however invalidate any +other reasons why the referencing files, or any +produced executables, might be covered by the GNU +General Public License. + +This exception applies only to the code released +by its author under the Litt Perl Development +Tools License. Such code must clearly state that +it's covered by the Litt Perl Development Tools +License. If you copy code from other GNU-GPL +compatible software, as the General Public License +permits, the exception does not apply to the code +that you add in this way. To avoid misleading +anyone as to the status of such modified files, +you must delete this exception notice from them. + +If you write modifications of your own for +software licensed under the Litt Perl Development +Tools License, it is your choice whether to permit +this exception to apply to your modifications. If +you do not wish that, delete this exception +notice. + +This exception cannot be applied to software whose +license, End User License Agreement, or Terms Of +Use limit reverse engineering or discussion about +the software. This exception cannot be applied to +software incorporating any type of software +patents. + + +THE EXCEPTION TO THE EXCEPTION + +The intent of the Litt Perl Development Tools +License (LPDTL) is to produce a free software +development environment enabling a software +developer to create free software, nonfree +software, or proprietary software. Therefore, all +of the resulting program's software development +features must be contained in the LPDTL licensed +software, or in GPL licensed software. It is a +violation of the LPDTL to place any software +development features in any file not licensed +under either the GPL or the LPDTL. + +A "software development feature" is a feature +enabling creation or modification of software. + + +DISCUSSION OF INTENT OF THIS LICENSE + +You can find a discussion of the intent of this +license in the LPDTL_discuss.txt file. If you +haven't been given a copy of this file, you can +find it in the +http://www.troubleshooters.com/licenses/LPDTL/ +directory. diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.GPL b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.GPL new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.LPDTL.1.0 b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.LPDTL.1.0 new file mode 100644 index 0000000..0e7003c --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/COPYING.LPDTL.1.0 @@ -0,0 +1,118 @@ +The Litt Perl Development Tools License +Version 1.0, 3/14/2003 +--------------------------------------- + +The Litt Perl Development Tools License (LPDTL) +consists of the GNU GPL plus an exception, plus an +exception to that exception. + +This program is free software; you can +redistribute it and/or modify it under the terms +of version 2 of the GNU General Public License as +published by the Free Software Foundation. + +This program is distributed in the hope that it +will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General +Public License along with this software; see the +file COPYING.GPL. If not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite +330, Boston, MA 02111-1307 USA. Other locations +for the GNU General Public License include: + + http://www.troubleshooters.com/licenses/LPDTL/COPYING.GPL + +and + + http://www.gnu.org/licenses/gpl.txt + + +THE EXCEPTION + +As a special exception, the author of this Perl +Development Tool gives permission for additional +uses of the text contained in this Perl +Development Tool. + +The exception is that, if you reference the LPDTL +licensed software, by use of a Perl "use" or +"require" statement, from other files, this does +not by itself cause the files referencing this +Perl Development Tool to be covered by the GNU +General Public License. Your use of the +referencing files is in no way restricted on +account of their referencing the code in this Perl +Development Tool. + +Likewise, if you link the LPDTL licensed software +with other files to produce an executable, this +does not by itself cause the resulting executable +to be covered by the GNU General Public License. +Your use of that executable is in no way +restricted on account of linking the LPDTL +licensed software's code into it. + + +EXCEPTION LIMITATIONS + +This exception does not however invalidate any +other reasons why the referencing files, or any +produced executables, might be covered by the GNU +General Public License. + +This exception applies only to the code released +by its author under the Litt Perl Development +Tools License. Such code must clearly state that +it's covered by the Litt Perl Development Tools +License. If you copy code from other GNU-GPL +compatible software, as the General Public License +permits, the exception does not apply to the code +that you add in this way. To avoid misleading +anyone as to the status of such modified files, +you must delete this exception notice from them. + +If you write modifications of your own for +software licensed under the Litt Perl Development +Tools License, it is your choice whether to permit +this exception to apply to your modifications. If +you do not wish that, delete this exception +notice. + +This exception cannot be applied to software whose +license, End User License Agreement, or Terms Of +Use limit reverse engineering or discussion about +the software. This exception cannot be applied to +software incorporating any type of software +patents. + + +THE EXCEPTION TO THE EXCEPTION + +The intent of the Litt Perl Development Tools +License (LPDTL) is to produce a free software +development environment enabling a software +developer to create free software, nonfree +software, or proprietary software. Therefore, all +of the resulting program's software development +features must be contained in the LPDTL licensed +software, or in GPL licensed software. It is a +violation of the LPDTL to place any software +development features in any file not licensed +under either the GPL or the LPDTL. + +A "software development feature" is a feature +enabling creation or modification of software. + + +DISCUSSION OF INTENT OF THIS LICENSE + +You can find a discussion of the intent of this +license in the LPDTL_discuss.txt file. If you +haven't been given a copy of this file, you can +find it in the +http://www.troubleshooters.com/licenses/LPDTL/ +directory. diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/INSTALL b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/INSTALL new file mode 100644 index 0000000..03615a8 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/INSTALL @@ -0,0 +1,23 @@ +INSTALLATION PROCEDURES FOR Node.pm + Version 0.2.0 released 5/13/2004 + +Downloading + Download from + http://www.troubleshooters.com/projects/Node/Node.#.#.#.tgz +Installing + The tarball extracts into a directory called Node + cd to the directory into which you want to place Node + Move any existing Node directory out of the way + tar xzvf Node.#.#.#.tgz +Testing + cd into the Node directory + ./hello.pl + troubleshoot as necessary +Using + In any perl program using Node not in the Node directory... + Use following code at beginning + #!/usr/bin/perl -w -I/path/to/Node + use strict; + use Node; + If destination machine has unknown Node.pm directory... + See example_nodepath.pl diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/LPDTL_discuss.txt b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/LPDTL_discuss.txt new file mode 100644 index 0000000..9ee1b08 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/LPDTL_discuss.txt @@ -0,0 +1,26 @@ +INTENT OF THE LITT PERL DEVELOPMENT TOOL LICENSE + +The intent of the Litt Perl Development Tool License (LPDTL) is to provide +programmers with a development tool that is copylefted free software without +requiring applications built from this tool to be free software. + +I (Steve Litt) have tried to craft the LPDTL to prevent "cute and +innovative" ways of taking this tool private. For instance, a person might +try to make the LPDTL licensed code dependent on subroutines in proprietary +subroutines. This is why the LPDTL has a clause stating that all +*development* features must reside in the LPDTL code, or in GPL code, but +not non-GPL-compatible code. + +Although the LPDTL allows its use with software of almost any license, it +specifically forbids use with licenses doing any of the following: + +1. Restricting reverse engineering + +2. Restricting discussion about the software + +3. Code that includes software patents + +I feel that restrictions on reverse engineering and discussion, and software +patents, are so destructive to society, that I have included language +preventing use of LPDTL licensed code with any software incorporating any of +these three atrocities. diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/Node.pm b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/Node.pm new file mode 100644 index 0000000..cec1f97 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/Node.pm @@ -0,0 +1,475 @@ +#!/usr/bin/perl -w + +####################################################################### +# Copyright (C) 2003 by Steve Litt, all rights reserved. +# Licensed under version 1 of the +# Litt Perl Development Tools License +# See COPYING file +# Or COPYING.LPDTL.1.0 +# Or see http://www.troubleshooters.com/licenses/LPDTL/COPYING.LPDTL.1.0 +# +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK! +# +# Version 0.2.0 released 5/13/2004 + +use strict; + +package Node; +sub new($$$$) + { + my($typeOfClass) = $_[0]; + my($self) = {}; + bless($self, $typeOfClass); + + $self->{'name'}=$_[1]; + $self->{'type'}=$_[2]; + $self->{'value'}=$_[3]; + + + $self->{'nextsibling'}=undef; + $self->{'prevsibling'}=undef; + $self->{'parent'}=undef; + $self->{'firstchild'}=undef; + $self->{'lastchild'}=undef; + + $self->{'attributes'}={}; + + return($self); + } + + +#### For single attribute +sub setAttribute() + { + $_[0]->{'attributes'}->{$_[1]} = $_[2]; + } + +sub removeAttribute() + { + delete $_[0]->{'attributes'}->{$_[1]}; + } + +sub getAttribute() + { + if($_[0]->hasAttributes()) + { + return $_[0]->{'attributes'}->{$_[1]}; + } + else + { + return(undef); + } + } + +sub hasAttribute() + { + if($_[0]->hasAttributes()) + { + return defined($_[0]->getAttribute($_[1])); + } + else + { + return(undef); + } + } + +#### For attribute array +sub hasAttributes() + { + return defined($_[0]->getAttributes()); + } +sub getAttributes() + { + return %{$_[0]->{'attributes'}}; + } + +sub setAttributes() + { + $_[0]->{'attributes'} = $_[1]; + } + + + + +#### For traversing +sub getFirstChild() {return($_[0]->{'firstchild'});} +sub getNextSibling() {return($_[0]->{'nextsibling'});} +sub getParent() {return($_[0]->{'parent'});} + +sub hasFirstChild() {return(defined($_[0]->{'firstchild'}));} +sub hasNextSibling() {return(defined($_[0]->{'nextsibling'}));} +sub hasParent() {return(defined($_[0]->{'parent'}));} + +#### For reverse traversing +sub getLastChild() {return($_[0]->{'lastchild'});} +sub getPrevSibling() {return($_[0]->{'prevsibling'});} + +sub hasLastChild() {return(defined($_[0]->{'lastchild'}));} +sub hasPrevSibling() {return(defined($_[0]->{'prevsibling'}));} + +#### For content +sub getName() {return($_[0]->{'name'});} +sub getType() {return($_[0]->{'type'});} +sub getValue() {return($_[0]->{'value'});} +sub setName() {$_[0]->{'name'} = $_[1];} +sub setType() {$_[0]->{'type'} = $_[1];} +sub setValue() {$_[0]->{'value'} = $_[1];} + +sub hasName() {return(defined($_[0]->{'name'}));} +sub hasType() {return(defined($_[0]->{'type'}));} +sub hasValue() {return(defined($_[0]->{'value'}));} + +#### For setting pointers, should probably be private or protected +sub setFirstChild() {$_[0]->{'firstchild'} = $_[1];} +sub setNextSibling() {$_[0]->{'nextsibling'} = $_[1];} +sub setParent() {$_[0]->{'parent'} = $_[1];} +sub setLastChild() {$_[0]->{'lastchild'} = $_[1];} +sub setPrevSibling() {$_[0]->{'prevsibling'} = $_[1];} + +#### For creation +sub insertSiblingBeforeYou() + { + my($self) = $_[0]; + my($oldPrevSibling) = $self->getPrevSibling(); + $self->setPrevSibling($_[1]); + $self->getPrevSibling()->setParent($self->getParent()); + $self->getPrevSibling()->setNextSibling($self); + if(!defined($oldPrevSibling)) + { + $self->getParent()->setFirstChild($self->getPrevSibling()); + $self->getPrevSibling()->setPrevSibling(undef); + } + else + { + $self->getPrevSibling()->setPrevSibling($oldPrevSibling); + $oldPrevSibling->setNextSibling($self->getPrevSibling()); + } + return($self->getPrevSibling()); + } + +sub insertSiblingAfterYou() + { + my($self) = $_[0]; + my($oldNextSibling) = $self->getNextSibling(); + $self->setNextSibling($_[1]); + $self->getNextSibling()->setParent($self->getParent()); + $self->getNextSibling()->setPrevSibling($self); + if(!defined($oldNextSibling)) + { + if(defined($self->getParent())) + { + $self->getParent()->setLastChild($self->getNextSibling()); + } + $self->getNextSibling()->setNextSibling(undef); + } + else + { + $self->getNextSibling()->setNextSibling($oldNextSibling); + $oldNextSibling->setPrevSibling($self->getNextSibling()); + } + return($self->getNextSibling()); + } + +sub insertFirstChild() + { + my($self) = $_[0]; + my($oldFirstChild) = $self->getFirstChild(); + if(defined($oldFirstChild)) + { + $oldFirstChild->insertSiblingBeforeYou($_[1]); + } + else + { + $self->setFirstChild($_[1]); + $self->setLastChild($_[1]); + $self->getFirstChild()->setParent($self); + } + return($self->getFirstChild()); + } + +sub insertLastChild() + { + my($self) = $_[0]; + my($oldLastChild) = $self->getLastChild(); + if(defined($oldLastChild)) + { + $oldLastChild->insertSiblingAfterYou($_[1]); + } + else + { + $self->setFirstChild($_[1]); + $self->setLastChild($_[1]); + $self->getFirstChild()->setParent($self); + } + return($self->getLastChild()); + } + +#### For cloning +sub clone() + { + my($self) = $_[0]; + my($clone) = Node->new(); + $clone->setName($self->getName()); + $clone->setType($self->getType()); + $clone->setValue($self->getValue()); + + $clone->setParent($self->getParent()); + $clone->setFirstChild($self->getFirstChild()); + $clone->setLastChild($self->getLastChild()); + $clone->setPrevSibling($self->getPrevSibling()); + $clone->setNextSibling($self->getNextSibling()); + return($clone); + } + +#### For deletion +sub deleteSelf() + { + my($self) = $_[0]; + my($prev) = $self->getPrevSibling(); + my($next) = $self->getNextSibling(); + my($parent) = $self->getParent(); + if((defined($self->getPrevSibling()))&&(defined($self->getNextSibling()))) + { + $self->getNextSibling()->setPrevSibling($self->getPrevSibling()); + $self->getPrevSibling()->setNextSibling($self->getNextSibling()); + } + elsif((!defined($self->getPrevSibling()))&&(!defined($self->getNextSibling()))) + { + $self->getParent()->setFirstChild(undef); + $self->getParent()->setLastChild(undef); + } + elsif(!defined($self->getPrevSibling())) + { + $self->getParent()->setFirstChild($self->getNextSibling()); + $self->getNextSibling()->setPrevSibling(undef); + } + elsif(!defined($self->getNextSibling())) + { + $self->getParent()->setLastChild($self->getPrevSibling()); + $self->getPrevSibling()->setNextSibling(undef); + } + $self->setFirstChild(undef); + $self->setLastChild(undef); + } + +sub deleteTree() + { + my($self) = $_[0]; + +# #### Code to delete children and decendents here + $self->deleteSelf(); + } + +package OutlineParser; +sub new() + { + my($typeOfClass) = $_[0]; + my($self) = {}; + bless($self, $typeOfClass); + $self->{'head'} = Node->new("Header Node", "Head", "Inserted by OutlineParser"); + $self->{'fromstdin'} = 1; + $self->{'zapblanks'} = 1; + return($self); + } + +sub setCommentChar($$) + { + $_[0]->{'commentchar'} = $_[1]; + } + +sub getCommentChar($) + { + return($_[0]->{'commentchar'}); + } + +sub hasCommentChar($) + { + return(defined($_[0]->{'commentchar'})); + } + +sub getFirstNonBlankChar($$) + { + my $self = shift; + my $line = shift; + chomp $line; + my @parts = split(/\s+/,$line, 2); + $line = join('', @parts); + my $firstchar = substr($line, 0, 1); + return $firstchar; + } + + +sub parse() + { + my($self) = $_[0]; + my($fname) = $_[1]; + + my(@levelStack); + push(@levelStack, ($self->{'head'})); + my($checker) = $self->{'head'}; + my($lineno) = 0; + my($prevLevel) = -1; + + my($inf); + if($self->{'fromstdin'} == 0) + { + defined($fname) or die "OutlineParser::parse() requires a filename argument, terminating.\n"; + open(INF, "<" . $fname) or die "OutlineParser::parse() could not open $fname for input, terminating.\n"; + $inf = q(INF); + } + else + { + $inf = qw(STDIN); + } + while(<$inf>) + { + my($line) = $_; + chomp($line); + $lineno++; + my $zapFlag = 0; + my $firstNonBlankChar = $self->getFirstNonBlankChar($line); + if(($self->{'zapblanks'} != 0) && ($firstNonBlankChar eq '')) + { + $zapFlag = 1; + } + if($self->hasCommentChar() && ($self->getCommentChar() eq $firstNonBlankChar)) + { + $zapFlag = 1; + } + + unless($zapFlag) + { + my($level) = 0; + + $line =~ m/^( *)(.*)/; + if(defined($1)) + { + $level = length($1); + $line = $2; + } + else + { + $line = $2; + } + + my $node = Node->new("", "Node", $line); + $node->setAttribute('_lineno', $lineno); + + if($level == $prevLevel) + { + $levelStack[$prevLevel]->insertSiblingAfterYou($node); + $levelStack[$level] = $node; + } + elsif($level == $prevLevel + 1) + { + $levelStack[$prevLevel]->insertFirstChild($node); + $levelStack[$level] = $node; + } + elsif($level > $prevLevel + 1) + { + die "Multiple indent at line $lineno, \"$line\", terminating.\n"; + } + elsif($level < $prevLevel) + { + my($dedent) = $prevLevel - $level; + while($level < $prevLevel) + { + pop(@levelStack); + $prevLevel--; + } + $levelStack[$prevLevel]->insertSiblingAfterYou($node); + $levelStack[$level] = $node; + } + $prevLevel = $level; + } + } + if($self->{'fromstdin'} == 0) {close(INF);} + return($self->getHead()); + } + +sub fromStdin() {$_[0]->{'fromstdin'} = 1;} +sub fromFile() {$_[0]->{'fromstdin'} = 0;} +sub zapBlanks() {$_[0]->{'zapblanks'} = 1;} +sub dontZapBlanks() {$_[0]->{'zapblanks'} = 0;} +sub getHead() {return($_[0]->{'head'});} + + +package Walker; +sub new() + { + my $typeOfClass = $_[0]; + my $self = {}; + bless($self, $typeOfClass); + $self->{'top'} = $_[1]; + $self->{'entrycallback'} = $_[2]; + $self->{'exitcallback'} = $_[3]; + return($self); + } + +sub walk() + { + my($self) = $_[0]; + my($ascending) = 0; + my($checker)=$self->{'top'}; # like a checker you move around a board + my($level)=0; + my($continue) = 1; + my $counter = 0; + while($continue) + { + if($ascending == 0) + { + if(defined($self->{'entrycallback'})) + { + my @args = @{$self->{'entrycallback'}}; + my $sub = shift(@args); + push(@args, ($checker, $level)); + &{$sub}(@args); + } + if($level < 0) {$continue=0;} ## Callback sets negative to terminate + } + else + { + if(defined($self->{'exitcallback'})) + { + my @args = @{$self->{'exitcallback'}}; + my $sub = shift(@args); + push(@args, ($checker, $level)); + &{$sub}(@args); + } + if($level < 0) {$continue=0;} ## Callback sets negative to terminate + if($checker == $self->{'top'}) {$continue=0;} + } + + if($continue == 0) + { + #skip this if/elsif/else entirely + } + elsif(($ascending == 0) && (defined($checker->getFirstChild()))) + { + $ascending = 0; + $checker = $checker->getFirstChild(); + $level++; + } + elsif((defined($checker->getNextSibling())) && ($checker != $self->{'top'})) + { + $ascending = 0; + $checker = $checker->getNextSibling(); + } + elsif(defined($checker->getParent())) + { + $ascending = 1; + $checker = $checker->getParent(); + $level--; +# if($level < 1) {$continue = 0;} + } + else + { + $continue = 0; + } + $counter++; + } + } + + +1; + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/README.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/README.otl new file mode 100644 index 0000000..2d10d5e --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/README.otl @@ -0,0 +1,177 @@ +MANUAL FOR THE Node.pm Tool + Version 0.2.0 released 5/13/2004 +License + Litt Perl Development Tools License, version 1 + See COPYING file + This license is the GNU GPL with an exception + See COPYING.GPL + NO WARRANTY!!!!! See COPYING.GPL +Purpose + Handling hierarchies in Perl + Implements a tree of nodes + Each node has a name, a type, a value, and optionally attributes + Each node can have zero, one or many attributes + Each attribute has a name and a value + Especially made to handle tab indented outlines in memory +Learning Node.pm + Learn from the example programs: Study them in this order: + example_hello.pl + example_parse.pl + example_otl2markup.pl + example_attribs.pl + example_bylevel.pl + example_delete.pl + example_insert.pl + example_nodepath.pl + That's the only way to learn this tool + Do each example program in order + Run + Read + Study + Example programs + example_hello.pl + Proof of concept + 7 lines of perl + Instantiate and read from a Node object + example_parse.pl + Parse a tab indented outline file into a Node tree + Use a Walker object to walk the tree and print the Nodes + Create a Callback object and callback routine + example_otl2markup.pl + Use return callback to create end tags + example_attribs.pl + Set and get Node attributes + Observer "_lineno" attribute, + which was set by the Parser object + example_bylevel.pl + Read the Node tree recursively and output by level + Use the Callbacks object to store information + Use multiple callbacks to simplify a complex algorithm + Observe that the performance is still quite good + example_delete.pl + Delete nodes during a callback + Observe that the Walker object takes the deletion in stride + Observe that the Walker object does not "lose its place" + example_insert.pl + Insert nodes + Build a Node tree without an outline or Parser object + Create child nodes using an array + Create child nodes from a callback routine + Use a return callback to count occurrences within in its subtree + Access and use a Node's name, type and value + Move nodes within the tree + example_nodepath.pl + Load a Node.pm file in a different directory + Load a Node.pm file at runtime from an entry in a config file + Use an environment variable to change the name of the config file +File manifest + Documentation + INSTALL + README.otl + Licensing + COPYING + COPYING.GPL + COPYING.LPDTL.1.0 + LPDTL_discuss.txt + Node.pm file + + Node.pm + Example Programs + example_hello.pl + example_parse.pl + example_otl2markup.pl + example_attribs.pl + example_bylevel.pl + example_delete.pl + example_insert.pl + example_nodepath.pl + Sample node path config file (for example_nodepath.pl) + myapp.cfg + Sample outline (used for example_delete.pl) + deletetest.otl +Objects + Node.pm implements three object types: + Node + OutlineParser + Walker + Node + A single element in the hierarchy + All nodes connected + Parent pointer + (the pointer is a Perl reference, of course) + First child pointer + Last child pointer + Previous sibling pointer + Last sibling pointer + Each node has: + A name + hasName() + getName() + setName() + A type + hasType() + getType() + setType() + A value + hasValue() + getValue() + setValue() + Zero, one or many attributes + Each attribute has a name and a value + Single attribute methods: + hasAttribute() + getAttribute() + setAttribute() + removeAttribute() + Attribute array methods: + hasAttributes() + getAttributes() + setAttributes() + Node methods enable all hierarchy operations + Node insertion + insertFirstChild() + insertLastChild() + insertSiblingBeforeYou() + insertSiblingAfterYou() + Node deletion + deleteSelf() + Low level node traversal + hasFirstChild() + getFirstChild() + hasLastChild() + getLastChild() + hasPrevSibling() + getPrevSibling() + hasNextSibling() + getNextSibling() + hasParent() + getParent() + OutlineParser + Object to convert a tab indented outline to a tree of Node objects + Outline must be well formed... + Each line indented zero or one tab to the right of its parent + You can set and access properties of the parse + hasCommentChar() + getCommentChar() + setCommentChar() + fromStdin() + fromFile() + zapBlanks() + dontZapBlanks() + After setting parse properties, you perform the parse + my parser = OutlinerParser->new(); + parser->setCommentChar('#'); + parser->fromFile(); + my $topNode = parser->parse("myoutline.txt"); + Walker + Object to traverse entire Node hierarchy + Performs actions via callback routines + my $walker = Walker->new($topNode, $entryCallbackRef, $returnCallbackRef); + Entry callback occurs when node is first accessed + Return callback occurs when node is re-accessed after going through children + Callbacks should be object methods, not freestanding + Callbacks must take 3 arguments: + $self: The object containing the callback + [\&Callbacks::cbPrintNodeInfo, $callbacks]); +Installation + See INSTALL file diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/deletetest.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/deletetest.otl new file mode 100644 index 0000000..e7d34da --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/deletetest.otl @@ -0,0 +1,18 @@ +Top + Level2 + Level2b + Level3 + deleteme + gone + gone + deleteme + gone + gone + this should stay + deleteme + deleteme + gone + gone + Level3b + 2level2 +Top2 diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_attribs.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_attribs.pl new file mode 100755 index 0000000..d82610f --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_attribs.pl @@ -0,0 +1,162 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +##################################################################### +# This exercise demonstrates the use of attributes for each node. +# Attributes are facts about an entity, rather than an entity itself. +# In real practice, many times attributes can be substituted for nodes +# and vice versa. However, an attribute CANNOT have children. +# +# This is the first exercise using multiple Walker objects. The first +# Walker object counts each node's children, and if the node has +# children, it creates an attribute named "children" for that node. +# The value of the attribute is the number of direct children for +# that node. +# +# Nodes are accessed two ways in the cbPrintNode() callback. The entire +# attribute hash is accessed with hasAttributes and getAttributes(), +# while single named attributes are accessed with hasAttributes and +# getAttributes(). +# +# One more action that's demonstrated is the use of secondary navigation +# within a callback routine. For each node, the callback routine +# navigates to the first child and then each successive sibling of that +# child in order to count the direct children. This is a common +# algorithm with Node.pm. It might look inefficient, and you might be +# tempted to perform the count during the callback that prints the +# information. Don't do it. Multiple walkers help keep Node.pm +# enabled programs easy to understand and modify. Because the +# entire node tree is in memory, the double navigation isn't +# particularly slow. +# +# Real world programs make heavy use of multiple walkers. For instance, +# the EMDL to UMENU program (not packaged here) has over 10 walkers. +# +##################################################################### + +use strict; # prevent hard to find errors + +use Node; # Use Note.pm tool + +package Callbacks; +sub new() + { + my($type) = $_[0]; + my($self) = {}; + bless($self, $type); + $self->{'errors'} = 0; + $self->{'warnings'} = 0; + return($self); + } + +sub getErrors(){return $_[0]->{'errors'};} +sub getWarnings(){return $_[0]->{'warnings'};} + +sub cbCountChildren() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} + + my $childCount=0; + if($checker->hasFirstChild()) + { + $childCount++; + my $checker2 = $checker->getFirstChild(); + while($checker2->hasNextSibling()) + { + $childCount++; + $checker2 = $checker2->getNextSibling(); + } + $checker->setAttribute("children", $childCount); + } + } + +sub cbPrintNode() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + for(my $n=0; $n < $level; $n++) {print "\t";} + print "* "; + print $checker->getValue(); # print the text of the node + print "\n"; + + for(my $n=0; $n <= $level; $n++) {print "\t";} + print "("; + + my %attribs = {}; + %attribs = $checker->getAttributes() if $checker->hasAttributes(); + + my @keys = keys(%attribs); + foreach my $key (sort @keys) + { + print $key, "=", $attribs{$key}, "; "; + } + + print ")\n"; + + if($checker->hasAttribute("children")) + { + for(my $n=0; $n <= $level; $n++) {print "\t";} + print "This node has "; + print $checker->getAttribute("children"); + print " children.\n"; + } + } + +package Main; + +sub main() + { + #### PARSE FROM FILE README.otl + my $parser = OutlineParser->new(); # instantiate parser + $parser->setCommentChar("#"); # ignore lines starting with # + $parser->fromFile(); # get input from file + my $topNode=$parser->parse("README.otl"); + + #==================================================================== + # The preceding statement parses file README.otl into a node hierarchy + # and assigns the top level node of that hierarchy to $topNode. When + # you run the program you'll notice that the text in $topNode does + # not appear in README.otl, but instead has value + # "Inserted by OutlineParser". + # + # This is a feature, not a bug. In order to accommodate the typical + # case of an outline having several top level items, and yet still + # be able to represent the whole hierarchy as a single top node, + # the OutlineParser object creates a new node with value + # " Inserted by OutlineParser" + # and places all the outline's top level items under that newly + # created node. + # + # If the outline you're working on is guaranteed to have only + # a single top level item, and if you want that to be the top + # level node, you can simply do the following: + # + # $topNode=$topNode->getFirstChild(); + #==================================================================== + + #### INSTANTIATE THE Callbacks OBJECT + my $callbacks = Callbacks->new(); + + #### WALK THE NODE TREE, + #### OUTPUTTING LEVEL AND TEXT + my $walker = Walker->new + ( + $topNode, + [\&Callbacks::cbCountChildren, $callbacks] + ); + $walker->walk(); + my $walker = Walker->new + ( + $topNode, + [\&Callbacks::cbPrintNode, $callbacks] + ); + $walker->walk(); + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_bylevel.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_bylevel.pl new file mode 100755 index 0000000..d60d7f6 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_bylevel.pl @@ -0,0 +1,227 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +use strict; # prevent hard to find errors + +use Node; # Use Node.pm tool + +##################################################################### +# The Walker object walks the node hierarchy recursively. That is, +# it goes deep before going laterally. That's just what's needed for +# many applications. However, sometimes it's necessary to look at +# one level at a time. +# +# There are many ways to accomplish this. Some involve sorting and +# merging. Many involve arrays of nodes on a given level, and +# plunging one deep into each one. +# +# In this example we'll start with a walker that assigns the full +# path to each node as an attribute of that node. We'll then loop +# through all levels starting with 0, and for each one we'll print all +# children of nodes at that level. Every time there's a parent change, +# we'll print a header for that parent. +# +# This example also illustrates the use of variables within the +# Callback object. You might have wondered why callbacks must be +# part of an object rather than free floating functions. The answer +# is that the use of callbacks as object methods means that we can +# keep totals and break logic variables within the callback object, +# thereby eliminating the (nasty) necessity of global variables. +# +# We cannot simply pass variables into and out of callback +# routines because, by the very nature of a callback routine, +# its arguments and return type are strictly predefined. In the +# case of Node.pm the arguments are always $self, $checker and +# $level. To get any other information into or out of the callback +# routine, we must use a non-callback method of the same object. +# +# It should be noted that there's nothing wrong with having +# multiple callback objects. If there are numerous callback +# routines it might make sense to group them by functionality, +# or by totals and persistent variables they must keep track of. +# +# As you run, study and understand this code, be aware that converting +# a hierarchy to a list by levels is a very difficult and complex task. +# Imagine keeping a list of children, and for each level using those +# children to find the next generation, and rewriting the array. Or +# prepending a level number followed by a child index on each line, +# and then sorting the whole array by the level number and child +# index, and finally running a routine to output the formatted +# output, complete with break logic and headers. +# +# Now consider how easy Node.pm made this job. First, a trivial +# Walker to calculate full paths, then a level loop calling a +# Walker to print only children of nodes at the desired level. The +# code is short, and it's very readable and understandable. The +# callback routines are short enough that you can safely use non- +# structured techniques such as returning from the middle instead +# of using nested if statements. The result is even more readability. +# +# One could make the (very valid) point that nodes are visited many +# times to process each once, and that this is not efficient in +# terms of runtime performance. Absolutely true! +# +# However, the programming simplicity prevents truly collosal +# efficency problems, such as cascading intermediate files, sorts, +# and the various other CPU cycle grabbers that seem to crop up +# in complex algorithms. And remember, the entire tree is in memory, +# with navigation via simple pointers, so the environment of Node.pm +# favors runtime speed. +# +# Case in point. My original EMDL to UMENU converter was such an +# epic production that I needed to study it for 4 hours every time +# I made a minor improvement. I had developed it using informal OOP +# and structured techniques, and had paid close attention to +# efficiency. The resulting program took 15 seconds to convert a +# 2300 line EMDL file. +# +# I rewrote the converter using Node.pm. This was a complete +# rewrite -- all new code -- no salvage. It was so much simpler +# that I wrote it in 12 hours. But I was very concerned with +# runtime. If the 15 seconds doubled, this would be a hassle, +# and if it quadrupled it would be totally impractical. When +# I ran it, the program did everything the original did, but +# did it in 2 seconds. Node.pm had given me a 7 fold speed +# increase. +# +##################################################################### + +package Callbacks; +sub new() + { + my($type) = $_[0]; + my($self) = {}; + bless($self, $type); + $self->{'errors'} = 0; + $self->{'warnings'} = 0; + $self->{'childrenatlevel'} = 0; + $self->{'currentlevel'} = 0; + $self->{'previousparentfullpath'} = "initialize"; + return($self); + } + +sub getErrors(){return $_[0]->{'errors'};} +sub getWarnings(){return $_[0]->{'warnings'};} + +sub getChildrenAtLevel(){return $_[0]->{'childrenatlevel'};} +sub setChildrenAtLevel(){$_[0]->{'childrenatlevel'} = $_[1];} +sub incChildrenAtLevel(){$_[0]->{'childrenatlevel'}++;} + +sub getCurrentLevel(){return $_[0]->{'currentlevel'};} +sub setCurrentLevel(){$_[0]->{'currentlevel'} = $_[1];} + +sub cbCalculateFullPath() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + if($checker->hasParent) + { + my $fullpath = $checker->getParent()->getAttribute("fullpath"); + $fullpath .= "/"; + $fullpath .= $checker->getValue(); + $checker->setAttribute("fullpath", $fullpath); + } + else + { + $checker->setAttribute("fullpath", $checker->getValue()); + } + } + +sub cbPrintNode() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + #### DO NOTHING UNLESS THIS NODE IS AT THE CURRENTLY SOUGHT LEVEL + return unless $level == $self->getCurrentLevel(); + + #### DO NOTHING UNLESS THIS NODE HAS CHILDREN + return unless $checker->hasFirstChild(); + + #### PRINT HEADER + print "\n", $checker->getAttribute("fullpath"), "\n"; + + #### PRINT CHILDREN AND COUNT CHILDREN AT LEVEL + my $checker2 = $checker->getFirstChild(); # We returned if there wasn't one + print "\t", $checker2->getValue(), "\n"; + $self->incChildrenAtLevel(); + + while($checker2->hasNextSibling()) + { + $checker2 = $checker2->getNextSibling(); + print "\t", $checker2->getValue(), "\n"; + $self->incChildrenAtLevel(); + } + } + + +package Main; + +sub main() + { + #### PARSE FROM FILE README.otl + my $parser = OutlineParser->new(); # instantiate parser + $parser->setCommentChar("#"); # ignore lines starting with # + $parser->fromFile(); # get input from file + my $topNode=$parser->parse("README.otl"); + + + #### INSTANTIATE THE Callbacks OBJECT + my $callbacks = Callbacks->new(); + + #### WALK THE NODE TREE, + #### CALCULATING FULL PATHS AND PUTTING THEM IN AN ATTRIBUTE + my $walker = Walker->new + ( + $topNode, # start with this node + [\&Callbacks::cbCalculateFullPath, $callbacks] # do this on entry to each node + ); + $walker->walk(); + + #### PRINT LEVEL 0 + print "\n\n********** BEGIN LEVEL ", "0", "\n"; + print "\t", $topNode->getValue(), "\n"; + + #### SET STARTING PARENT LEVEL, + #### AND SET $childCount SO THE LOOP WILL FIRE THE FIRST TIME + my $level=0; + my $childCount=9999; + + #================================================================== + # The main loop follows, level by level. At each level, nodes are + # queried for their children, which are then printed below the + # node's full path. The result is a list of nodes sorted by + # level. + # + # We add 1 to the level in the level header because we're referring + # to the level of the children, not of the current node. We keep + # looping to deeper levels until a level counts no children. + # + # This logic result in an empty level header at the bottom. If this + # were a big concern, we could print the level headers in the + # Callbacks::cbPrintNode() callback, with slightly altered logic. + # However, it's a minor point, so for simplicity we print the + # level header at the top of this loop in the main routine. + #================================================================== + while($childCount > 0) + { + print "\n\n********** BEGIN LEVEL ", $level + 1, "\n"; + $callbacks->setChildrenAtLevel(0); + $callbacks->setCurrentLevel($level); + my $walker = Walker->new + ( + $topNode, + [\&Callbacks::cbPrintNode, $callbacks] + ); + $walker->walk(); + $childCount = $callbacks->getChildrenAtLevel(); + $level++; + } + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_delete.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_delete.pl new file mode 100755 index 0000000..810507b --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_delete.pl @@ -0,0 +1,107 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +use strict; # prevent hard to find errors + +use Node; # Use Node.pm tool + +##################################################################### +# This exercise demonstrates the deletion of nodes. +# +# Because Perl is a garbage collection language, node deletion +# DOES NOT deallocate memory and the like. However, in the absense +# of a copy of the node, it will be garbage collected and unavailable. +# Also, the deletion process specificly undef's the deleted node's +# first and last children. +# +# You noticed I mentioned keeping a copy. The algorithm of a Walker +# object moves a node around the tree like a checker. Calling +# $checker->deleteSelf() does not render $checker undefined. In fact, +# it still has its parent, nextSibling and previousSibling pointers +# intact. What this means is that the Walker's next iteration goes +# to exactly the same node as it would have if the deletion had not +# taken place. In other words, you do not need to "move the checker +# back one" after a deletion. +# +# This makes deletion algorithms very simple. +# +# There may come a time when you want to delete a node but keep its +# children. In that case, you must first attach its children to nodes +# that will not be deleted. +# +##################################################################### + +package Callbacks; +sub new() + { + my($type) = $_[0]; + my($self) = {}; + bless($self, $type); + $self->{'errors'} = 0; + $self->{'warnings'} = 0; + return($self); + } + +sub getErrors(){return $_[0]->{'errors'};} +sub getWarnings(){return $_[0]->{'warnings'};} + +sub cbDelete() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + #### DELETE THIS NODE IF ITS VALUE CONTAINS deleteme + my $text = "init"; + $text = $checker->getValue() if $checker->hasValue(); + if($text =~ m/deleteme/) + { + $checker->deleteSelf(); + } + } + +sub cbPrintNode() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} + + for(my $n=0; $n < $level; $n++) {print "\t";} + print $checker->getValue(), "\n"; + } + +package Main; + +sub main() + { + #### PARSE FROM FILE README.otl + my $parser = OutlineParser->new(); + $parser->setCommentChar("#"); + $parser->fromFile(); + my $topNode=$parser->parse("deletetest.otl"); + + #### INSTANTIATE THE Callbacks OBJECT + my $callbacks = Callbacks->new(); + + #### WALK THE NODE TREE, + #### DELETING NODES WITH "deleteme" IN THEM + my $walker = Walker->new + ( + $topNode, + [\&Callbacks::cbDelete, $callbacks] + ); + $walker->walk(); + + #### WALK THE NODE TREE, + #### OUTPUTTING LEVEL AND TEXT + $walker = Walker->new + ( + $topNode, + [\&Callbacks::cbPrintNode, $callbacks] + ); + $walker->walk(); + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_hello.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_hello.pl new file mode 100755 index 0000000..cf46fad --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_hello.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +use strict; # prevent hard to find errors +use Node; + +my $topNode = Node->new("myname", "mytype", "myvalue"); +print "\n::: "; +print $topNode->getName(), " ::: "; +print $topNode->getType(), " ::: "; +print $topNode->getValue(), " :::\n"; diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_insert.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_insert.pl new file mode 100755 index 0000000..4fd82fa --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_insert.pl @@ -0,0 +1,550 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +use strict; # prevent hard to find errors + +use Node; # Use Node.pm tool + +##################################################################### +# WARNING: This is a difficult exercise. Do not attempt this exercise +# until you have completed the prerequisites listed in the README.otl +# file. +# +# I suggest you approach this example starting with the main routine +# at the bottom of the file, and then drilling down into subroutines +# and callbacks. Understand the big picture before drilling down. +# +# This exercise demonstrates insertion of nodes, and much, much more. +# Insertion is accomplished by the insertFirstChild(), +# insertSiblingBeforeYou(), insertSiblingAfterYou(), and +# insertLastChild() methods. The insertLastChild() method is not +# demonstrated. +# +# This exercise is VERY contrived. It is contrived to show techniques +# of building a node tree using insertions, and also how to switch +# two nodes. The switching of the two nodes is especially contrived, +# but I could think of no better way of demonstrating node moving. +# +# This exercise builds a tree that represents a date book type calendar. +# Level 0 is Calender, level 1 are the years, of which there is only 2004, +# Level 2 are the months, level 3 the days, and level 4 the hour long +# timeslots. There is no provision for weekends, nor after hours +# appointments. It is a demonstration only. +# +# Using an array of month names and an array of days per month, you build +# the month and day levels using a nested loop. The hour level is built +# using a Walker. Node names are things like "January" or 31 or +# "11:00-12:00". Node types are things like "Year", "Month", "Day" or +# "Hour". Node values are undefined unless an appointment is made, in +# which case the value is the node text. +# +# A special Walker is used to mark any day, month or year entities +# if they contain appointments. Specifically, all appointments in that +# day, month or year are counted, and that number of stars are placed +# beside the day, month or year. This is implemented by using an +# return callback so that by the time the callback is called, all children +# have been calculated. +# +##################################################################### + +package Callbacks; +sub new() + { + my($type) = $_[0]; + my($self) = {}; + bless($self, $type); + $self->{'errors'} = 0; + $self->{'warnings'} = 0; + return($self); + } + +sub getErrors(){return $_[0]->{'errors'};} +sub getWarnings(){return $_[0]->{'warnings'};} + +#================================================================= +# The cbMakeMarks() callback is called on return to a node from +# its children (return callback). It executes only on year, month +# and day nodes. It iterates through all its immediate children, +# totalling up the "appointments" attribute and setting its +# own attribute to that total. Remember, because this is a +# callback triggered on return from children, it is guaranteed +# that all children have been counted, and that all those children +# have totalled their children, etc. +# +# In the case of a day node, instead of totalling the "appointments" +# attribute, it counts the number of hour nodes with defined values. +# A defined value on an hour node is an appointment. +# +# Last but not least, on non-zero counts, this callback sets the +# day, month or year node's value to a number of asterisks equal +# to the number of appointments in its subtree. +# +# Read this code carefully. Once you understand it, you'll have +# many insights to Node.pm. +#================================================================= +sub cbMakeMarks() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + #### PROCESS ONLY DAY, MONTH OR YEAR NODES + unless ( + $checker->getType() eq "Day" || + $checker->getType() eq "Month" || + $checker->getType() eq "Year" + ) + { + return; + } + + my $count = 0; + my $childNode = $checker->getFirstChild(); + while(defined($childNode)) + { + if($checker->getType() eq "Day") + { + if(defined($childNode->getValue())) + { + $count++; + } + } + else + { + if($childNode->hasAttribute("appointments")) + { + $count += $childNode->getAttribute("appointments"); + } + } + $childNode = $childNode->getNextSibling(); + } + $checker->setAttribute("appointments", $count); + if($count > 0) + { + my $string; + for(my $n=0; $n < $count; $n++){$string .= '*';} + $checker->setValue($string); + } + } + +#================================================================= +# The cbInsertHours() callback operates ONLY on day nodes. When +# called from a day node, it inserts hourlong appointment slots +# starting at 8am and ending at 5pm. The code is pretty +# straightforward. +#================================================================= +sub cbInsertHours() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + + return unless $checker->getType() eq "Day"; # Insert hours under days only + + my $checker2; + for(my $n=8; $n <= 16; $n++) + { + my $startHour = "$n:00"; + my $n2 = $n + 1; + my $endHour = "$n2:00"; + my $node = Node->new("$startHour" . "-" . "$endHour", "Hour", undef); + if($checker->hasFirstChild()) + { + $checker2 = $checker2->insertSiblingAfterYou($node); + } + else + { + $checker2 = $checker->insertFirstChild($node); + } + } + } + +#================================================================= +# The cbPrintNode() callback prints the name of the node, +# and its value if a value is defined. It's very straighforward. +#================================================================= +sub cbPrintNode() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + #### DON'T PRINT LEVEL 0 (CALENDER) + return if $level == 0; + + for(my $n=1; $n < $level; $n++) { print "\t";} + + print $checker->getName() if $checker->hasName(); + print ": "; + + print $checker->getValue() if $checker->hasValue(); + print "\n"; + } + + +#================================================================= +# The cbPrintNodeDiagnosic() callback is not used, but provided +# for any necessary debugging. +#================================================================= +sub cbPrintNodeDiagnostic() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + + for(my $n=0; $n < $level; $n++) { print "\t";} + + print ">"; + print $checker->getName() if $checker->hasName(); + print " ::: "; + + print $checker->getType() if $checker->hasType(); + print " ::: "; + + print $checker->getValue() if $checker->hasValue(); + print "<\n"; + } + +package Main; + +########################################################################### +# The insertDays() subroutine handles insertion of days below all +# month nodes. +########################################################################### +sub makeAppointments($) + { + my $yearNode = shift; + #### MARCH 22 AT 8AM + my $monthNode = $yearNode->getFirstChild() -> #January + getNextSibling() -> #February + getNextSibling(); #March + my $dayNode = $monthNode->getFirstChild(); + while($dayNode->getName() != 22) + { + $dayNode = $dayNode->getNextSibling(); + unless(defined($dayNode)) + { + die "No March 22\n"; + } + } + my $hourNode = $dayNode->getFirstChild(); + $hourNode->setValue("Spring Cleaning"); + + #### JUNE 22 AT 9AM + #### WRONGLY LABELED AS FALL FESTIVAL + #### INSTEAD OF SUMMER BREAK + $monthNode = $monthNode->getNextSibling() -> # April + getNextSibling() -> # May + getNextSibling(); # June + $dayNode = $monthNode->getFirstChild(); + while($dayNode->getName() != 22) + { + $dayNode = $dayNode->getNextSibling(); + unless(defined($dayNode)) + { + die "No June 22\n"; + } + } + $hourNode = $dayNode->getFirstChild()->getNextSibling(); + $hourNode->setValue("Fall Festival"); + + #### SEPTEMBER 22 AT 10AM + #### WRONGLY LABELED AS FALL FESTIVAL + #### INSTEAD OF SUMMER BREAK + $monthNode = $monthNode->getNextSibling() -> # July + getNextSibling() -> # August + getNextSibling(); # September + $dayNode = $monthNode->getFirstChild(); + while($dayNode->getName() != 22) + { + $dayNode = $dayNode->getNextSibling(); + unless(defined($dayNode)) + { + die "No September 22\n"; + } + } + $hourNode = $dayNode -> getFirstChild() -> #8-9 + getNextSibling() -> # 9-10 + getNextSibling(); # 10-11 + $hourNode->setValue("Summer Break"); + + #### DECEMBER 22 FROM 3PM TO 5PM (2 TIMESLOTS) + #### HAPPY HOLIDAYS PARTY + $monthNode = $monthNode->getNextSibling() -> # October + getNextSibling() -> # November + getNextSibling(); # December + $dayNode = $monthNode->getFirstChild(); + while($dayNode->getName() != 22) + { + $dayNode = $dayNode->getNextSibling(); + unless(defined($dayNode)) + { + die "No December 22\n"; + } + } + $hourNode = $dayNode->getFirstChild(); + while($hourNode->getName() ne "15:00-16:00") + { + $hourNode = $hourNode->getNextSibling(); + unless(defined($hourNode)) + { + die "No 4pm slot\n"; + } + } + $hourNode->setValue("Happy Holidays Party"); + $hourNode = $hourNode->getNextSibling(); + $hourNode->setValue("Happy Holidays Party"); + + #### DECEMBER 30 AT 9AM BUY PARTY SUPPLIES + while($dayNode->getName() != 30) + { + $dayNode = $dayNode->getNextSibling(); + unless(defined($dayNode)) + { + die "No December 30\n"; + } + } + $hourNode = $dayNode->getFirstChild()->getNextSibling(); + $hourNode->setValue("Buy Party Supplies"); + } + +########################################################################### +# The insertMonthsAndDays() subroutine handles insertion of months +# below the year, and days below every month. It works by iterating through +# an array of months, and finding number of days in an array of month +# lengths. It does NOT use the Node.pm navigational system to find months. +# Use of the Node.pm navigational system for this purpose is demonstrated +# in the insertion of hours in all days. +# +# Note that we could have avoided using a nested loop by using a Walker +# and associated callback to install the days under every month. In such +# a case the array of month lengths would have been placed in the Callback +# object. However, for the sake of variety, we chose to use a nested loop +# to load the months and days. +########################################################################### +sub insertMonthsAndDays($) + { + my $yearNode = shift; + my $checker = $yearNode; + my $checker2; + my @monthNames=("January", "February", "March", "April", "May", + "June", "July", "August", "September", "October", + "November", "December"); + my @monthLengths=(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + my $monthSS = 0; + foreach my $monthName (@monthNames) + { + my $node = Node->new($monthName, "Month", undef); + $node->setAttribute("days", $monthLengths[$monthSS]); + if($yearNode->hasFirstChild()) + { + $checker = $checker->insertSiblingAfterYou($node); + } + else + { + $checker = $yearNode->insertFirstChild($node); + } + for(my $n=1; $n <= $monthLengths[$monthSS]; $n++) + { + $node = Node->new($n, "Day", undef); + if($checker->hasFirstChild()) + { + $checker2 = $checker2->insertSiblingAfterYou($node); + } + else + { + $checker2 = $checker->insertFirstChild($node); + } + } + $monthSS++; + } + } + +########################################################################### +# This subroutine switches the June 22 9am appointment and the +# September 22 10am appointment. In each case, both the appointment +# text and the time needed switching. +# +# The sane way to accomplish this task would have been to modify +# the nodes in place. However, this subroutine was created solely to +# demonstrate the movement of nodes, so that's what we did. +# +# Note that the fact that the two are at different times complicates the +# situation. It's not enough to just trade nodes -- the Sept 9am node +# must be placed after the existing June 10am node, which itself is after +# the erroneous June 9am node containing what should be September's +# appointment. After such placement, the original June 9am node must +# have its name updated so that it is a 10am node. A similar process +# takes place for September. The original nodes are also deleted. +# +# Please follow the (convoluted and contrived) logic: +# 1. Store the June hour node in $juneNode +# 2. Store the September hour node in $septNode +# 3. After the existing June 10am, place a CLONE of the Sept appointment +# 4. Before the existing Sept 9am, place a CLONE of the June appointment +# 5. Delete the original June appointment +# 6. Delete the original September appointment +# 7. On the original June 10am node, make it 9am +# 8. On the original September 9am node, make it 10am +########################################################################### +sub switchJuneAndSeptemberAppointments($) + { + my $yearNode = shift; + + #### FIND NODE FOR JUNE 22 9AM APPOINTMENT + my $juneNode = $yearNode->getFirstChild(); + while(defined($juneNode)) + { + last if $juneNode->getName() eq "June"; + $juneNode = $juneNode->getNextSibling(); + } + die "Cannot find month of June\n" unless defined($juneNode); + + $juneNode = $juneNode->getFirstChild(); + while(defined($juneNode)) + { + last if $juneNode->getName() eq "22"; + $juneNode = $juneNode->getNextSibling(); + } + die "Cannot find June 22\n" unless defined($juneNode); + + $juneNode = $juneNode->getFirstChild(); + while(defined($juneNode)) + { + last if $juneNode->getName() eq "9:00-10:00"; + $juneNode = $juneNode->getNextSibling(); + } + die "Cannot find June 22 at 9am\n" unless defined($juneNode); + + #### FIND NODE FOR SEPTEMBER 22 10AM APPOINTMENT + my $septNode = $yearNode->getFirstChild(); + while(defined($septNode)) + { + last if $septNode->getName() eq "September"; + $septNode = $septNode->getNextSibling(); + } + die "Cannot find month of September\n" unless defined($septNode); + + $septNode = $septNode->getFirstChild(); + while(defined($septNode)) + { + last if $septNode->getName() eq "22"; + $septNode = $septNode->getNextSibling(); + } + die "Cannot find September 22\n" unless defined($septNode); + + $septNode = $septNode->getFirstChild(); + while(defined($septNode)) + { + last if $septNode->getName() eq "10:00-11:00"; + $septNode = $septNode->getNextSibling(); + } + die "Cannot find September 22 at 9am\n" unless defined($septNode); + + #### SWITCH THE NODES + my $newJune = $juneNode->getNextSibling()->insertSiblingAfterYou($septNode->clone()); + my $newSept = $septNode->getPrevSibling()->insertSiblingBeforeYou($juneNode->clone()); + $juneNode->deleteSelf(); + $septNode->deleteSelf(); + + #### FIX NAMES OF SURROUNDING CLONES + $newJune->getPrevSibling()->setName("9:00-10:00"); + $newSept->getNextSibling()->setName("10:00-11:00"); + + return; + } + + +########################################################################### +# In the main routine, you carry out or delegate the following tasks +# in order to create an appointment calendar: +# 1. Insert single level 0 and 1 nodes +# 2. Instantiate the Callbacks object +# 3. Insert all month and day nodes +# 4. Insert all hour nodes +# 5. Make appointments +# erroneously switching the june 22 & Sept 22 appointments +# 6. Mark days, months and years containing appointments +# 7. Output the calendar +# 8. Switch back June22 and Sept22 +# 9. Re mark days, months and years +# 10. Output a separator between bad and good calendars +# 11. Re output the calendar +# +########################################################################### +sub main() + { + #### INSERT SINGLE LEVEL 0 AND 1 NODES + my $topNode=Node->new("Calender", "Calender", "Calender"); + my $yearNode=$topNode->insertFirstChild(Node->new("2004", "Year", undef)); + + #### INSTANTIATE THE Callbacks OBJECT + my $callbacks = Callbacks->new(); + + #### INSERT MONTH AND DAY NODES + insertMonthsAndDays($yearNode); + + #### INSERT THE HOURS USING A Walker + my $walker = Walker->new + ( + $topNode, + [\&Callbacks::cbInsertHours, $callbacks] + ); + $walker->walk(); + + + #### MAKE A FEW APPOINTMENTS + #### ACCIDENTALLY SWITCHING SUMMER AND FALL + makeAppointments($yearNode); + + #### MARK DAYS, MONTHS AND YEAR THAT HAVE APPOINTMENTS + #### USING A WALKER WITH ONLY A RETURN CALLBACK + $walker = Walker->new + ( + $topNode, + undef, + [\&Callbacks::cbMakeMarks, $callbacks] + ); + $walker->walk(); + + #### WALK THE NODE TREE, + #### OUTPUTTING THE CALENDER + $walker = Walker->new + ( + $topNode, # start with this node + [\&Callbacks::cbPrintNode, $callbacks] # do this on entry to each node + ); + $walker->walk(); + + #### CORRECT THE MISTAKE + #### SWITCH JUNE 22 AND SEPT 22 + switchJuneAndSeptemberAppointments($yearNode); + + #### RE-MARK DAYS, MONTHS AND YEAR THAT HAVE APPOINTMENTS + #### USING A WALKER WITH ONLY A RETURN CALLBACK + $walker = Walker->new + ( + $topNode, + undef, + [\&Callbacks::cbMakeMarks, $callbacks] + ); + $walker->walk(); + + #### OUTPUT A SEPARATOR BETWEEN ORIGINAL AND CORRECTED CALENDARS + for (my $n=0; $n<5; $n++) + { + print "######################################################\n"; + } + + #### RE-WALK THE NODE TREE, + #### RE-OUTPUTTING THE CALENDER + $walker = Walker->new + ( + $topNode, # start with this node + [\&Callbacks::cbPrintNode, $callbacks] # do this on entry to each node + ); + $walker->walk(); + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_nodepath.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_nodepath.pl new file mode 100755 index 0000000..033b1fd --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_nodepath.pl @@ -0,0 +1,135 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +use strict; # prevent hard to find errors + +##################################################################### +# Node.pm is a tool you will probably use in many projects located +# in varying directories. How do you enable those projects to +# include Node.pm? Here are some ways: +# 1. Place Node.pm in the project's directory +# 2. Place Node.pm on Perl's module path +# 3. Run the project as perl -I/path/to/Node project.pl +# 4. Shebang line #!/usr/bin/perl -w -I/path/to/Node +# +# Number 1 can become problematic as the number of apps using Node.pm +# increases. If you have 30 different copies in 30 different directories, +# how do you keep them all up to date. +# +# Number 2 is a much better option. It works. However, which @INC +# directory do you place it in? When you update Perl or your distribution, +# it goes away. +# +# Number 3 is great, except you need to create a shellscript to call +# Perl with your program as an argument. BE SURE not to leave a space +# between the -I and the directory, or that space actually becomes +# part of the directory. +# +# Number 4 is greater, because it doesn't require a shellscript. Once +# again, no space between -I and the directory. In all cases where +# you know what directory will contain Node.pm, number 4 is a great +# alternative. +# +# But what if you don't know in advance what directory +# will contain Node.pm? What if you're writing an application to be +# run at varying locations with varying setups? What if, in addition, +# you don't want the end user messing with the source code to change +# the shebang line? In that case, you can actually place the path +# to Node.pm in a configuration file. It takes several lines of code, +# but it's certainly nice to be able to accommodate the user's +# environment without requiring change to the source code. +# +# This exercise demonstrates how to set the Node.pm location from a +# configuration file. Once again, if you're the sole user it might be +# better to change the shebang line, but if you're distributing +# your program like the autumn leaves, a configuration file is the +# way to go. +# +##################################################################### + + +##################################################################### +# The loadNodeModule() subroutine is a complete substitute for: +# use Node +# +# It includes: +# require Node; +# import Node; +# +# The preceding two calls completely replace a use Node statement, +# and better still, unlike the use statement, they happen at +# runtime instead of compile time. Therefore, this subroutine reads +# the directory from a config file, then executes that directory +# with the proper require and import statements. Obviously, the +# loadNodeModule() subroutine must be executed before any code depending +# on the Node.pm module is executed. +##################################################################### +sub loadNodeModule() + { + #### CHANGE THE FOLLOWING TO CHANGE THE DEFAULT APP FILENAME + my $defaultConfFileName = "./myapp.cfg"; + + #### CHANGE THE FOLLOWING TO CHANGE APP FILENAME ENVIRONMENT VAR + my $envVarName = "MY_APP_CONFIG"; + + my($conffile) = $ENV{$envVarName}; + print $conffile, "\n" if defined $conffile; + $conffile = $defaultConfFileName unless defined($conffile); + print "Using config file $conffile.\n"; + + open CONF, '<' . $conffile or die "FATAL ERROR: Could not open config file $conffile."; + my @lines = ; + close CONF; + + my @nodedirs; + foreach my $line (@lines) + { + chomp $line; + if($line =~ m/^\s*nodedir\s*=\s*([^\s]*)/) + { + my $dir = $1; + if($dir =~ m/(.*)\$HOME(.*)/) + { + $dir = $1 . $ENV{'HOME'} . $2; + } + push @nodedirs, ($dir); + } + } + + if(@nodedirs) + { + unshift @INC, @nodedirs; + } + + require Node; + import Node; + } + +##################################################################### +# The main() routine calls loadNodeModule to include Node.pm, +# and then runs a few lines of code to conclusively prove that +# Node.pm is loaded. It also prints out the @INC array to show that +# directory in which Node.pm resides is now in the @INC path. +# +# Note that in the absense of any change to the environment variable +# defined in loadNodeModule(), the configuration file will be ./myapp.cfg. +##################################################################### +sub main() + { + loadNodeModule(); + my $topNode = Node->new("myname", "mytype", "myvalue"); + print "\n::: "; + print $topNode->getName(), " ::: "; + print $topNode->getType(), " ::: "; + print $topNode->getValue(), " :::\n"; + foreach my $line (@INC) + { + print $line, "\n"; + } + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_otl2markup.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_otl2markup.pl new file mode 100755 index 0000000..79d53cb --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_otl2markup.pl @@ -0,0 +1,123 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +##################################################################### +# This exercise demonstrates use of the return callback routine. The +# return callback routine occurs when node navigation returns to a +# node from its children. Therefore, the return callback routine is +# never executed by nodes without children. +# +# An obvious use of the return callback routine is to print end tags +# for nested markup. A node's end tag must follow all markup for all +# the node's children, so the return callback is perfect for that +# purpose. +# +# Because childless nodes never execute the return callback routine, +# in the case of childless nodes this program prints the end tags +# from the entry callback routine. +# +# This program prints the attributes of each Node object. You'll +# immediately note that the "children" attributes you set are printed. +# But you'll also observe that a "_lineno" attribute has been set for +# all nodes except the top one. That attribute was set by the Parser +# object, and corresponds to the line in the parsed outline file. This +# attribute is extremely helpful in printing error messages. +##################################################################### + + +use strict; # prevent hard to find errors + +use Node; # Use Note.pm tool + +package Callbacks; +sub new() + { + my($type) = $_[0]; + my($self) = {}; + bless($self, $type); + $self->{'errors'} = 0; + $self->{'warnings'} = 0; + return($self); + } + +sub getErrors(){return $_[0]->{'errors'};} +sub getWarnings(){return $_[0]->{'warnings'};} + +############################################################## +# cbPrintTag is the entry callback, and is called on first +# entry to each node. It prints the start tag and text. If +# the node is a leaf level node, it also prints the end tag +# on the same line. +############################################################## +sub cbPrintTag() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} + + #### PRINT START TAG AND CONTENT + for(my $n = 0; $n < $level; $n++) {print "\t";} + print ""; + print $checker->getValue() if $checker->hasValue(); + + #### IF THIS IS A LEAF LEVEL ITEM, PRINT THE + #### END TAG IMMEDIATELY. OTHERWISE, THE + #### RETURN CALLBACK WILL TAKE CARE OF THE END TAG. + unless($checker->hasFirstChild()) + { + print ""; + } + + #### PRINT NEWLINE + print "\n"; + } + +############################################################## +# cbPrintEndTag is the return callback, and is called on reentry +# to the node, after all its children have been processed. +# It is not called by leaf level (childless) nodes. The purpose +# of this routine is to print the end tag. +# +# For nodes with children, the end tag must be printed after +# all information for the node's children has been printed, +# in order to preserve proper nesting. +############################################################## +sub cbPrintEndTag() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} + + #### PRINT END TAG FOR PARENT + for(my $n = 0; $n < $level; $n++) {print "\t";} + print ""; + print "\n"; + } + +package Main; + +sub main() + { + #### PARSE FROM FILE README.otl + my $parser = OutlineParser->new(); + $parser->setCommentChar("#"); + $parser->fromFile(); + my $topNode=$parser->parse("README.otl"); + + #### INSTANTIATE THE Callbacks OBJECT + my $callbacks = Callbacks->new(); + + #### WALK THE NODE TREE, + #### OUTPUTTING LEVEL AND TEXT + my $walker = Walker->new + ( + $topNode, # start with this node + [\&Callbacks::cbPrintTag, $callbacks], # do this on entry to each node + [\&Callbacks::cbPrintEndTag, $callbacks]# do this on return from node's children + ); + $walker->walk(); + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_parse.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_parse.pl new file mode 100755 index 0000000..8a2380e --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/example_parse.pl @@ -0,0 +1,114 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2004 by Steve Litt +# Licensed with the GNU General Public License, Version 2 +# ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK +# See http://www.gnu.org/licenses/gpl.txt + +use strict; # prevent hard to find errors + +use Node; # Use Node.pm tool + +##################################################################### +# This exercise demonstrates the most elemental use of Node.pm. +# It does nothing more than read README.otl into a Node tree, and +# then print the tree. +# +# Here's the high level logic: +# Set up a Callback object to house the callback routines +# Instantiate and configure a Parser object to parse README.otl +# Instantiate a Walker object to walk the resulting node tree +# Link Callbacks::cbPrintNode() as the Walker's entry callback +# +##################################################################### + +############################################################## +# You need an object to house callback routines. The object can +# be named anything, but it should have facilities to count up +# errors and warnings. Its new() method should always be something +# like what you see below, and there should have getErrors() and +# getWarnings() methods. +# +# The cbPrintNode() method is typical of a simple callback routine. +# All callback routines have exactly three arguments, $self, +# $checker and $level. $self refers to the object containing +# the callback routine, $checker is the node that called this +# callback routine, and $level is the level of that node in the +# hierarchy. Armed with these pieces of information, you can +# perform almost any operation on the current node ($checker). +# +# The callback routines are called by the Parser object during +# parsing. A callback routine can be called upon first entry +# into a node, or it can be called upon reentry into that node +# after processing all that node's children. The latter is +# an excellent way of outputting end tags at the proper time. +############################################################## +package Callbacks; +sub new() + { + my($type) = $_[0]; + my($self) = {}; + bless($self, $type); + $self->{'errors'} = 0; + $self->{'warnings'} = 0; + return($self); + } + +sub getErrors(){return $_[0]->{'errors'};} +sub getWarnings(){return $_[0]->{'warnings'};} + +sub cbPrintNode() + { + my($self, $checker, $level) = @_; + unless (defined($checker)) {return -999;} # don't process undef node + print $level, " ::: "; # print the level + print $checker->getValue(); # print the text of the node + print "\n"; + } + +package Main; + +sub main() + { + #### PARSE FROM FILE README.otl + my $parser = OutlineParser->new(); # instantiate parser + $parser->setCommentChar("#"); # ignore lines starting with # + $parser->fromFile(); # get input from file + my $topNode=$parser->parse("README.otl"); + + #==================================================================== + # The preceding statement parses file README.otl into a node hierarchy + # and assigns the top level node of that hierarchy to $topNode. When + # you run the program you'll notice that the text in $topNode does + # not appear in README.otl, but instead has value + # "Inserted by OutlineParser". + # + # This is a feature, not a bug. In order to accommodate the typical + # case of an outline having several top level items, and yet still + # be able to represent the whole hierarchy as a single top node, + # the OutlineParser object creates a new node with value + # " Inserted by OutlineParser" + # and places all the outline's top level items under that newly + # created node. + # + # If the outline you're working on is guaranteed to have only + # a single top level item, and if you want that to be the top + # level node, you can simply do the following: + # + # $topNode=$topNode->getFirstChild(); + #==================================================================== + + #### INSTANTIATE THE Callbacks OBJECT + my $callbacks = Callbacks->new(); + + #### WALK THE NODE TREE, + #### OUTPUTTING LEVEL AND TEXT + my $walker = Walker->new + ( + $topNode, # start with this node + [\&Callbacks::cbPrintNode, $callbacks] # do this on entry to each node + ); + $walker->walk(); + } + +main(); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/myapp.cfg b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/myapp.cfg new file mode 100644 index 0000000..26f7d89 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/Node/myapp.cfg @@ -0,0 +1,4 @@ +#### THIS FILE CONFIGURES example_nodepath.pl. +#### IN ORDER TO USE example_nodepath.pl, +#### CHANGE FOLLOWING PATH TO THE DIRECTORY WHERE YOU PLACED Node.pm #### +nodedir=/path/to/nodemodule diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/fs2otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/fs2otl new file mode 100755 index 0000000..33ce89e --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/fs2otl @@ -0,0 +1,7 @@ +#!/bin/sh +echo "$1" +echo "$1" | perl -pe 's/./-/g;' +cd "$1" +find . \ + | sort \ + | perl -pe 's|^\./||; s|[^/]+/|\t|g; s/([^\t])/[_] $1/;' diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.awk b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.awk new file mode 100644 index 0000000..b4ee4a4 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.awk @@ -0,0 +1,284 @@ +# *Title: otl2aft +# *Author: Todd Coram (http://maplefish.com/todd) +# *TOC +# +# ~Version 1.3~ +# +# ~This source is hereby placed into the Public Domain.~ +# ~What you do with it is your own business.~ +# ~Just please do no harm.~ +# +#------------------------------------------------------------------------ +# +# * Introduction +# +# Otl2aft converts VimOutliner files into +# [AFT (http://www.maplefish.com/todd/aft.html)] documents. This file +# can be run with nawk, mawk or gawk. +# +# This tool was created upon the request/inspiration of David J Patrick +#(of http://linuxcaffe.ca fame). +# +# You can downloaded the most up to date +# source [here (http://www.maplefish.com/todd/otl2aft.awk)]. +# A PDF version of this file resides +# [here (http://www.maplefish.com/todd/otl2aft.pdf)]. +# +# AEY: Changed all # symbols within regular expressions to \043 +# to avoid problems with # being the comment character. +# +# * Code +# +# In the beginning we want to print out the AFT title and author. +# We expect the otl file to contain two top level headlines. The first +# will be used as the title and the second as the author. +# +# We also print out some control bits and a table of contents placeholder. +# +BEGIN { + VERSION="v1.3 9/04/2009"; + # AEY: Note first line is now for OTL use only; we ignore it here. + getline; # expect title + print "#---SET-CONTROL tableparser=new" + # AEY: Commented out following lines, since this info is now metadata. + #print "*Title: " $0; + #getline; # expect author + #print "*Author: " $0; + #print "\n*TOC\n" +} + +# AEY: > now starts an inline comment. We ignore these. +/^[\t]+>/ { + next; +} + +# AEY: < is now used for metadata. We only act on certain ones. +#/^[\t]+<[ \t]*title:[ \t]*/ { +/^[\t]+| and if we discover a crosshatch |#|, we +# start a list. If we are already in a list, we continue the list. Both +# starting and continuing is handled by [handlelist]. +# +# AEY: Removed this +#/^[\t]+>/ { +# if (!list_level) reset(); +# gsub(/\t/,""); +# sub(/>/, ""); +# +# if (list_level || $0 ~ /[ ]*[\043*]/) { +# handlelist(); +# } +# print $0; next; +#} + +# Scan for |;| or |<| which indicate ''preformatted body text'' and +# ''user-defined preformatted text block'' respectively. Both of these +# are non wrapping but we ignore that (for now). We handle lists just like +# the previous scan action. +# +# AEY: Removed < handling +/^[\t]+;/ { # Handle ";" and "<" (preformated text) + if (!list_level) reset(); + gsub(/\t/,""); + sub(/;/, ""); + + if (list_level || $0 ~ /[ ]*\043/) { # Convert "< #" into numbered lists. + handlelist(); + } + print $0; next; +} + +# Scan for a table. This is tricky. We want to cast the Outliner table +# into the AFT ''new table'' format. AFT tables (especially as rendered +# by LaTeX) really want to have captions/headers. We fake that for now +# by using a |-| place holder. This should be fixed! +# +/^[\t]+\|/ { + if (!in_table) reset(); + in_table = 1 + gsub(/\t/,""); + if ($1 ~ /\|\|/) { + print "\t! _ !"; + print "\t!----------!" + } + gsub(/\|\|/,"!"); + gsub(/\|/,"!"); + print "\t"$0 + print "\t!----------!" + next; +} + +# The default scan matches anything not matching the above scan. We simply +# go through and set the known indent level based on the number of tabs +# seen. +# +{ match($0,/^[\t]+/); indent = RLENGTH; if (indent == -1) indent = 0; } + +# Given the iden level set by the default scan (above), we now determine +# what type of AFT output to do. +# +# Indent levels lower than 7 are represented directly +# using AFT sections. +# +# AEY: Added $0 = "*"$0; back in to ensure top-level headings remain headings! +# (This existed in earlier versions, but not in version 1.3.) +#indent < 7 { gsub(/\t/,"*"); print "";} +indent < 7 { gsub(/\t/,"*"); $0 = "*"$0; print "";} + +# Indent levels greater than 6 are represented by AFT bullet lists. +# This is done by first killing some tabs (we don't want to start off +# nesting too deeply), and using the remaining tabs to adjust to the +# appropriate list nesting level. +# +indent > 6 { + gsub(/\t\t\t/, ""); + match($0,/^[\t]+/); + remtabs = substr($0,RSTART,RLENGTH); + text = substr($0,RSTART+RLENGTH); + $0 = remtabs"* "text; + print ""; +} + +# After adjusting indentation, just print out the line. +# +{ print $0 } + +# **handlelist +# Look at the indentation and produce lists accordingly. +# +function handlelist() { + if (!list_level) { + list_indent = length(indent) + 1; + } + list_level = list_indent - length(indent); + + if ($0 ~ /[ ]*\043/) { # Convert " #" into numbered lists. + for (i=0; i < list_level; i++) + printf("\t"); + gsub(/[ ]*\\043/,"#."); + } else if ($0 ~ /[ ]*\*/) { # Convert " *" into bullet lists. + for (i=0; i < list_level; i++) + printf("\t"); + gsub(/[ ]*\*/,"*"); + } else if (list_level) { + for (i=0; i < list_level; i++) + printf("\t"); + } +} + +# **reset +# Reset various parameters to get us out of various modes. +# +function reset() { + if (list_level) { + print " "; + list_level = 0; + } + if (in_table) { + print "\t!----------!\n" + in_table = 0; + } +} + +# AEY: "Trim" function, added for sanity's sake. +function trim(str) { + sub(/^[ \t]*/,"",str); + sub(/[ \t]*$/,"",str); + return str; +} + +# AEY: Get everything to left of specified regex, and trim it too. +function leftpart(str,regex) { + if (match(str,regex)) { + return trim(substr(str,1,RSTART-1)); + } else { + return ""; + } +} + +# AEY: Get everything to right of specified regex, and trim it too. +function rightpart(str,regex) { + if (match(str,regex)) { + return trim(substr(str,RSTART+RLENGTH)); + } else { + return ""; + } +} + +# That's all folks! diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.pdf b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2aft.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8164a6b6c985fe485d54720b7a82e082f274458f GIT binary patch literal 82163 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 $;ob6S3pKt&$-%*%Z&D$3#M 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 W3)W+neV$S@MaG_i14oX_^ZXwz)~25T literal 0 HcmV?d00001 diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2docbook.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2docbook.pl new file mode 100755 index 0000000..ac7b698 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2docbook.pl @@ -0,0 +1,270 @@ +#!/usr/bin/perl + +use strict; +use XML::Writer; +use vars qw($writer $section_has_contents $VERSION); + +use constant DEBUG => 0; + +$VERSION = '2.0'; + +sub debug { + if ( DEBUG ) + { + print STDERR @_; + } +} + +sub start_docbook { + $writer = XML::Writer->new(DATA_MODE => 1, + DATA_INDENT => 1); + + debug(' 'x$writer->getDataIndent(), "starting new docbook\n"); + + $writer->xmlDecl(); + +# my $system = '/usr/share/sgml/docbook/xml-dtd-4.1/docbookx.dtd'; + my $system = 'http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd'; + + $writer->doctype('article', + '-//OASIS//DTD DocBook XML V4.1//EN', + $system); +} + +sub start_article { + my $id = shift; + + debug(' 'x$writer->getDataIndent(), "starting new article\n"); + + my @attributes = ( + 'class' => 'whitepaper', + ); + + if ( $id ) + { + push @attributes, ( 'id' => $id ); + } + + $writer->startTag('article', @attributes); +} + +sub start_section { + my $title = shift; + + debug(' 'x$writer->getDataIndent(), "starting new section\n"); + + $writer->startTag('section'); + + $section_has_contents = 0; + + if ( $title ) + { + $writer->dataElement('title', $title); + } +} + +sub start_list { + debug(' 'x$writer->getDataIndent(), "starting new list\n"); + + $writer->startTag('itemizedlist'); +} + +sub append_list_item { + my $text = shift; + + debug(' 'x$writer->getDataIndent(), "starting new listitem\n"); + + $writer->startTag('listitem'); + + $writer->dataElement('para', $text); + + $writer->endTag('listitem'); +} + +sub end_list { + $writer->endTag('itemizedlist'); + + debug(' 'x$writer->getDataIndent(), "ending list\n"); +} + +sub append_code { + my $code = shift; + + debug(' 'x$writer->getDataIndent(), "starting new programlisting\n"); + + $section_has_contents = 1; + + $writer->dataElement('programlisting', $code, role=>'C'); +} + +sub append_para { + my $text = shift; + + debug(' 'x$writer->getDataIndent(), "starting new para\n"); + + $section_has_contents = 1; + + $writer->dataElement('para', $text); +} + +sub end_section { + if ( ! $section_has_contents ) + { + $writer->emptyTag('para'); + $section_has_contents = 1; + } + + $writer->endTag('section'); + + debug(' 'x$writer->getDataIndent(), "ending section\n"); +} + +sub end_article { + $writer->endTag('article'); + + debug(' 'x$writer->getDataIndent(), "ending article\n"); +} + +sub end_docbook { + $writer->end(); + + debug(' 'x$writer->getDataIndent(), "ending docbook\n"); +} + +#################################################### + +start_docbook(); +start_article(); + +my $section_level = 0; +my $line; +my $para = ''; +my $list_mode = 0; +my $code_mode = 0; +my $first_line = 1; + +sub list_done { + if ( $list_mode ) { + end_list(); + $list_mode = 0; + } +} + +sub para_done { + if ( $para ) + { + chomp $para; + if ( $code_mode ) + { + append_code($para); + $code_mode = 0; + } + elsif ( $list_mode ) + { + append_list_item($para); + } + else + { + append_para($para); + } + } + $para = ''; +} + +while ( defined ($line = <>) ) +{ + if ( $first_line and $line =~ /^-\*-/ ) + { + next; + } + $first_line = 0; + + if ( $line =~ /^\t*\* (.*)/ ) + { + para_done(); + + $para = $1; + + if ( ! $list_mode ) + { + start_list(); + $list_mode = 1; + } + + next; + } + + if ( $line =~ /^\t*[^\t: ]/ ) + { + para_done(); + list_done(); + } + + if ( $line =~ /^(\t*)([^\t\n: ].*)/ ) + { + my $title = $2; + my $new_section_level = length($1) + 1; + + para_done(); + list_done(); + + for ( my $i = 0 ; $section_level - $new_section_level >= $i ; $i++ ) + { + end_section(); + } + + chomp $title; + start_section($title); + + $section_level = $new_section_level; + next; + } + +# Code mode not supported yet +# if ( ! $list_mode and $line =~ /^\s+/ ) +# { +# debug("enabling code mode\n"); +# $code_mode = 1; +# } + + $line =~ s/^\t*(\: ?| )//; + if ($line =~ /^$/) { + para_done(); + list_done(); + next; + } + $para .= $line; +} +para_done(); + +for ( my $i = 0 ; $section_level > $i ; $i++ ) +{ + end_section(); +} + +end_article(); +end_docbook(); + +__END__ + +=head1 NAME + +outline2dockbook - Generate DocBook XML from VimOutliner outline + +=head1 SYNOPSIS + +outline2docbook < input > output + +=head1 DESCRIPTION + +B reads an VimOutliner outline-mode type text file on +standard input and outputs DocBook XML on standard output. + +The original version was written by Thomas R. Fullhart to convert from Emacs +outline mode. It is available at +http://genetikayos.com/code/repos/outline2docbook/distribution/. + +This program uses the B perl module, which is available +on B. + +=cut diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html.py new file mode 100755 index 0000000..61be3cf --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html.py @@ -0,0 +1,1111 @@ +#!/usr/bin/python2 +# otl2html.py +# convert a tab-formatted outline from VIM to HTML +# +# Copyright 2001 Noel Henson All rights reserved +# +# ALPHA VERSION!!! + +########################################################################### +# Basic function +# +# This program accepts text outline files and converts them +# to HTML. The outline levels are indicated by tabs. A line with no +# tabs is assumed to be part of the highest outline level. +# +# 10 outline levels are supported. These loosely correspond to the +# HTML H1 through H9 tags. Alphabetic, numeric and bullet formats +# are also supported. +# +# CSS support has been added. +# + +########################################################################### +# include whatever mdules we need + +import sys +import re +import os +import time + +########################################################################### +# global variables + +formatMode = "indent" +copyright = "" +level = 0 +div = 0 +silentdiv = 0 +slides = 0 +hideComments = 0 +showTitle = 1 +inputFile = "" +outline = [] +flatoutline = [] +inBodyText = 0 # 0: no, 1: text, 2: preformatted text, 3: table +styleSheet = "nnnnnn.css" +inlineStyle = 0 + +########################################################################### +# function definitions + +# usage +# print the simplest form of help +# input: none +# output: simple command usage is printed on the console + + +def showUsage(): + print """ + Usage: + otl2html.py [options] inputfile > outputfile + Options + -p Presentation: slide show output for use with + HtmlSlides. + -D First-level is divisions (

) for making + pretty web pages. + -s sheet Use the specified style sheet with a link. This is the + default. + -S sheet Include the specified style sheet in-line the + output. For encapsulated style. + -T The first line is not the title. Treat it as + outline data + -c comments (line with [ as the first non-whitespace + character. Ending with ] is optional. + -C copyright Override the internal copyright notice with the + one supplied in the quoted string following this + flag. Single or double quotes can be used. + -H Show the file syntax help. + output is on STDOUT + Note: if neither -s or -S are specified, otl2html.py will default + to -s. It will try to use the css file 'nnnnnn.css' if it + exists. If it does not exist, it will be created automatically. + """ + + +def showSyntax(): + print """ + Syntax + Syntax is Vim Outliner's normal syntax. The following are supported: + + Text + : Body text marker. This text will wrap in the output. + ; Preformmated text. This text will will not wrap. + + Tables + || Table header line. + | Table and table columns. Example: + || Name | Age | Animal | + | Kirby | 9 | Dog | + | Sparky | 1 | Bird | + | Sophia | 8 | Cat | + This will cause an item to be left-justified. + | whatever | + This will cause an item to be right-justified. + | whatever | + This will cause an item to be centered. + | whatever | + This will cause an item to be default aligned. + | whatever | + + Character Styles + ** Bold. Example: **Bold Text** + // Italic. Example: //Italic Text// + +++ Highlight. Example: +++Highlight Text+++ + --- Strikeout. Example: ---Strikeout Text--- + Insane ---+++//**Wow! This is insane!**//+++--- + Just remember to keep it all on one line. + Horizontal Rule + ---------------------------------------- (40 dashes). + Copyright + (c) or (C) Converts to a standard copyright symbol. + + Including Images (for web pages) + [imagename] Examples: + [logo.gif] [photo.jpg] [car.png] + [http://i.a.cnn.net/cnn/.element/img/1.1/logo/logl.gif] + or from a database: + [http://www.lab.com/php/image.php?id=4] + + Including links (for web pages) + [link text-or-image] Examples: + [about.html About] [http://www.cnn.com CNN] + or with an image: + [http://www.ted.com [http://www.ted.com/logo.png]] + Links starting with a '+' will be opened in a new + window. Eg. [+about.html About] + + Including external files + !filename! Examples: + !file.txt! + + Including external outlines (first line is parent) + !!filename!! Examples: + !!menu.otl!! + + Including output from executing external programs + !!!program args!!! Examples: + !!!date +%Y%m%d!!! + + Note: + When using -D, the top-level headings become divisions (
) + and will be created using a class of the heading name. Spaces + are not allowed. If a top-level heading begins with '_', it + will not be shown but the division name will be the same as + without the '_'. Example: _Menu will have a division name of + Menu and will not be shown. + """ + + +# getArgs +# Check for input arguments and set the necessary switches +# input: none +# output: possible console output for help, switch variables may be set +def getArgs(): + global inputFile, debug, formatMode, slides, hideComments, copyright, \ + styleSheet, inlineStyle, div, showTitle + if (len(sys.argv) == 1): + showUsage() + sys.exit()() + else: + for i in range(len(sys.argv)): + if (i != 0): + if (sys.argv[i] == "-d"): + debug = 1 # test for debug flag + elif (sys.argv[i] == "-?"): # test for help flag + showUsage() # show the help + sys.exit() # exit + elif (sys.argv[i] == "-p"): # test for the slides flag + slides = 1 # set the slides flag + elif (sys.argv[i] == "-D"): # test for the divisions flag + div = 1 # set the divisions flag + elif (sys.argv[i] == "-T"): # test for the no-title flag + showTitle = 0 # clear the show-title flag + elif (sys.argv[i] == "-c"): # test for the comments flag + hideComments = 1 # set the comments flag + elif (sys.argv[i] == "-C"): # test for the copyright flag + copyright = sys.argv[i + 1] # get the copyright + i = i + 1 # increment the pointer + elif (sys.argv[i] == "-s"): # test for the style sheet flag + styleSheet = sys.argv[i + 1] # get the style sheet name + formatMode = "indent" # set the format + i = i + 1 # increment the pointer + elif (sys.argv[i] == "-S"): # test for the style sheet flag + styleSheet = sys.argv[i + 1] # get the style sheet name + formatMode = "indent" # set the format + inlineStyle = 1 + i = i + 1 # increment the pointer + elif (sys.argv[i] == "--help"): + showUsage() + sys.exit() + elif (sys.argv[i] == "-h"): + showUsage() + sys.exit() + elif (sys.argv[i] == "-H"): + showSyntax() + sys.exit() + elif (sys.argv[i][0] == "-"): + print "Error! Unknown option. Aborting" + sys.exit() + else: # get the input file name + inputFile = sys.argv[i] + + +# getLineLevel +# get the level of the current line (count the number of tabs) +# input: linein - a single line that may or may not have tabs at the beginning +# output: returns a number 1 is the lowest +def getLineLevel(linein): + strstart = linein.lstrip() # find the start of text in line + x = linein.find(strstart) # find the text index in the line + n = linein.count("\t", 0, x) # count the tabs + return(n + 1) # return the count + 1 (for level) + + +# getLineTextLevel +# get the level of the current line (count the number of tabs) +# input: linein - a single line that may or may not have tabs at the +# beginning +# output: returns a number 1 is the lowest +def getLineTextLevel(linein): + strstart = linein.lstrip() # find the start of text in line + x = linein.find(strstart) # find the text index in the line + n = linein.count("\t", 0, x) # count the tabs + n = n + linein.count(" ", 0, x) # count the spaces + return(n + 1) # return the count + 1 (for level) + + +# colonStrip(line) +# stip a leading ':', if it exists +# input: line +# output: returns a string with a stipped ':' +def colonStrip(line): + if (line[0] == ":"): + return line[1:].lstrip() + else: + return line + + +# semicolonStrip(line) +# stip a leading ';', if it exists +# input: line +# output: returns a string with a stipped ';' +def semicolonStrip(line): + if (line[0] == ";"): + return line[1:] + else: + return line + + +# dashStrip(line) +# stip a leading '-', if it exists +# input: line +# output: returns a string with a stipped '-' +def dashStrip(line): + if (line[0] == "-"): + return line[1:] + else: + return line + + +# pipeStrip(line) +# stip a leading '|', if it exists +# input: line +# output: returns a string with a stipped '|' +def pipeStrip(line): + if (line[0] == "|"): + return line[1:] + else: + return line + + +# plusStrip(line) +# stip a leading '+', if it exists +# input: line +# output: returns a string with a stipped '+' +def plusStrip(line): + if (line[0] == "+"): + return line[1:] + else: + return line + + +# handleBodyText +# print body text lines with a class indicating level, if style sheets +# are being used. otherwise print just

+# input: linein - a single line that may or may not have tabs at the beginning +# output: through standard out +def handleBodyText(linein, lineLevel): + global inBodyText + if (inBodyText == 2): + print "" + if (inBodyText == 3): + print "" + print "" + colonStrip(linein.strip()), + + +# handlePreformattedText +# print preformatted text lines with a class indicating level, if style sheets +# are being used. otherwise print just

+# input: linein - a single line that may or may not have tabs at the beginning
+# output: through standard out
+def handlePreformattedText(linein, lineLevel):
+    global inBodyText
+    if (inBodyText == 1):
+        print "

" + if (inBodyText == 3): + print "" + print "" + semicolonStrip(linein.strip()), + + +# isAlignRight +# return flag +# input: coldata, a string +def isAlignRight(coldata): + l = len(coldata) + if (coldata[0:2] == " ") and (coldata[l - 2:l] != " "): + return 1 + else: + return 0 + + +# isAlignLeft +# return flag +# input: coldata, a string +def isAlignLeft(coldata): + l = len(coldata) + if (coldata[0:2] != " ") and (coldata[l - 2:l] == " "): + return 1 + else: + return 0 + + +# isAlignCenter +# return flag +# input: coldata, a string +def isAlignCenter(coldata): + l = len(coldata) + if (coldata[0:2] == " ") and (coldata[l - 2:l] == " "): + return 1 + else: + return 0 + + +# getColumnAlignment(string) +# return string +# input: coldata +# output: +# or or or +def getColumnAlignment(coldata): + if isAlignCenter(coldata): + return '' + if isAlignRight(coldata): + return '' + if isAlignLeft(coldata): + return '' + return '' + + +# handleTableColumns +# return the souce for a row's columns +# input: linein - a single line that may or may not have tabs at the beginning +# output: string with the columns' source +def handleTableColumns(linein, lineLevel): + out = "" + coldata = linein.strip() + coldata = coldata.split("|") + for i in range(1, len(coldata) - 1): + out += getColumnAlignment(coldata[i]) + out += coldata[i].strip() + '' + return out + + +# handleTableHeaders +# return the souce for a row's headers +# input: linein - a single line that may or may not have tabs at the beginning +# output: string with the columns' source +def handleTableHeaders(linein, lineLevel): + out = "" + coldata = linein.strip() + coldata = coldata.split("|") + for i in range(2, len(coldata) - 1): + out += getColumnAlignment(coldata[i]) + out += coldata[i].strip() + '' + out = out.replace(' tag if necessary +# input: linein - a single line that may or may not have tabs at the beginning +# output: through standard out +def handleTable(linein, lineLevel): + global inBodyText + if (inBodyText == 1): + print "

" + if (inBodyText == 2): + print "
" + if (inBodyText != 3): + print "" + inBodyText = 3 + print handleTableRow(linein, lineLevel), + + +# linkOrImage +# if there is a link to an image or another page, process it +# input: line +# output: modified line +def linkOrImage(line): + line = re.sub('\[(\S+?)\]', '\\1', line) + line = re.sub('\[(\S+)\s(.*?)\]', '\\2', line) + line = re.sub('(', '\\1\\2" target=_new>', line) + line = line.replace('X', '[X]') + line = line.replace('_', '[_]') + return line + + +# tabs +# return a string with 'count' tabs +# input: count +# output: string of tabs +def tabs(count): + out = "" + if (count == 0): + return "" + for i in range(0, count - 1): + out = out + "\t" + return out + + +# includeFile +# include the specified file, if it exists +# input: line and lineLevel +# output: line is replaced by the contents of the file +def includeFile(line, lineLevel): + filename = re.sub('!(\S+?)!', '\\1', line.strip()) + incfile = open(filename, "r") + linein = incfile.readline() + while linein != "": + linein = re.sub('^', tabs(lineLevel), linein) + processLine(linein) + linein = incfile.readline() + incfile.close() + return + + +# includeOutline +# include the specified file, if it exists +# input: line and lineLevel +# output: line is replaced by the contents of the file +def includeOutline(line, lineLevel): + filename = re.sub('!!(\S+?)!!', '\\1', line.strip()) + incfile = open(filename, "r") + linein = incfile.readline() + linein = re.sub('^', tabs(lineLevel), linein) + processLine(linein) + linein = incfile.readline() + while linein != "": + linein = re.sub('^', tabs(lineLevel + 1), linein) + processLine(linein) + linein = incfile.readline() + incfile.close() + return + + +# execProgram +# execute the specified program +# input: line +# output: program specified is replaced by program output +def execProgram(line): + program = re.sub('.*!!!(.*)!!!.*', '\\1', line.strip()) + child = os.popen(program) + out = child.read() + err = child.close() + out = re.sub('!!!(.*)!!!', out, line) + processLine(out) + if err: + raise RuntimeError('%s failed w/ exit code %d' % (program, err)) + return + + +# divName +# create a name for a division +# input: line +# output: division name +def divName(line): + global silentdiv + line = line.strip() + if (line[0] == '_'): + silentdiv = 1 + line = line[1:] + line = line.replace(' ', '_') + return'
' + + +# getTitleText(line) +# extract some meaningful text to make the document title from the line +# input: line +# output: modified line +def getTitleText(line): + out = re.sub('.*#(.*)#.*', '\\1', line) + out = re.sub('<.*>', '', out) +# if (out != ""): out = re.sub('\"(.*?)\"', '\\1', line) + return(out) + + +# stripTitleText(line) +# strip the title text if it is enclosed in double-quotes +# input: line +# output: modified line +def stripTitleText(line): + out = re.sub('#\W*.*#', '', line) + return(out) + + +# beautifyLine(line) +# do some optional, simple beautification of the text in a line +# input: line +# output: modified line +def beautifyLine(line): + if (line.strip() == "-" * 40): + return "


" + + out = line + line = "" + + while (line != out): + line = out + # out = replace(out, '---', '', 1) + if (line[0].lstrip() != ";"): + out = re.sub('\-\-\-(.*?)\-\-\-', '\\1', out) + out = linkOrImage(out) + # out = replace(out, '**', '', 1) + out = re.sub('\*\*(.*?)\*\*', '\\1', out) + # out = replace(out, '//', '', 1) + out = re.sub('\/\/(.*?)\/\/', '\\1', out) + # out = replace(out, '+++', '', 1) + out = re.sub('\+\+\+(.*?)\+\+\+', '\\1', out) + out = re.sub('\(c\)', '©', out) + out = re.sub('\(C\)', '©', out) + return out + + +# closeLevels +# generate the number of or tags necessary to proplerly finish +# input: format - a string indicating the mode to use for formatting +# level - an integer between 1 and 9 that show the current level +# (not to be confused with the level of the current line) +# output: through standard out +def closeLevels(): + global level, formatMode + while (level > 0): + if (formatMode == "bullets"): + print "" + if (formatMode == "alpha") or (formatMode == "numeric") or \ + (formatMode == "roman") or (formatMode == "indent"): + print "" + + level = level - 1 + + +# processLine +# process a single line +# input: linein - a single line that may or may not have tabs at the beginning +# format - a string indicating the mode to use for formatting +# level - an integer between 1 and 9 that show the current level +# (not to be confused with the level of the current line) +# output: through standard out +def processLine(linein): + global level, formatMode, slides, hideComments, inBodyText, styleSheet, \ + inlineStyle, div, silentdiv + if (linein.lstrip() == ""): + return + linein = beautifyLine(linein) + lineLevel = getLineLevel(linein) + if ((hideComments == 0) or (lineLevel != linein.find("[") + 1)): + + if (lineLevel > level): # increasing depth + while (lineLevel > level): + if (formatMode == "indent" or formatMode == "simple"): + if (inBodyText == 1): + print"

" + inBodyText = 0 + elif (inBodyText == 2): + print"" + inBodyText = 0 + elif (inBodyText == 3): + print"
" + inBodyText = 0 + if not (div == 1 and lineLevel == 1): + print "
    " + else: + sys.exit("Error! Unknown formatMode type") + level = level + 1 + + elif (lineLevel < level): # decreasing depth + while (lineLevel < level): + if (inBodyText == 1): + print"

    " + inBodyText = 0 + elif (inBodyText == 2): + print"" + inBodyText = 0 + elif (inBodyText == 3): + print"" + inBodyText = 0 + print "
" + level = level - 1 + if (div == 1 and level == 1): + if (silentdiv == 0): + print'' + else: + silentdiv = 0 + print'
' + + else: + print # same depth + if (div == 1 and lineLevel == 1): + if (lineLevel != linein.find("!") + 1): + print divName(linein) + if (silentdiv == 0): + print "
    " + + if (slides == 0): + if (lineLevel == linein.find(" ") + 1) or \ + (lineLevel == linein.find(":") + 1): + if (inBodyText != 1): + handleBodyText(linein, lineLevel) + elif (colonStrip(linein.strip()) == ""): + print "

    " + handleBodyText(linein, lineLevel) + else: + print colonStrip(linein.strip()), + elif (lineLevel == linein.find(";") + 1): + if (inBodyText != 2): + handlePreformattedText(linein, lineLevel) + elif (semicolonStrip(linein.strip()) == ""): + print "" + handlePreformattedText(linein, lineLevel) + else: + print semicolonStrip(linein.strip()), + elif (lineLevel == linein.find("|") + 1): + if (inBodyText != 3): + handleTable(linein, lineLevel) + elif (pipeStrip(linein.strip()) == ""): + print "" + handleTable(linein, lineLevel) + else: + print handleTableRow(linein, lineLevel), + elif (lineLevel == linein.find("!!!") + 1): + execProgram(linein) + elif (lineLevel == linein.find("!!") + 1): + includeOutline(linein, lineLevel) + elif (lineLevel == linein.find("!") + 1): + includeFile(linein, lineLevel) + else: + if (inBodyText == 1): + print"

    " + inBodyText = 0 + elif (inBodyText == 2): + print"" + inBodyText = 0 + elif (inBodyText == 3): + print"" + inBodyText = 0 + if (silentdiv == 0): + print "" + \ + dashStrip(linein.strip()), + elif (lineLevel == linein.find("+ ") + 1): + print " class=\"LN" + str(lineLevel) + "\"", + print ">" + \ + plusStrip(linein.strip()), + else: + print " class=\"L" + str(lineLevel) + "\"", + print ">" + linein.strip(), + else: + silentdiv = 0 + else: + if (lineLevel == 1): + if (linein[0] == " "): + if (inBodyText == 0): + handleBodyText(linein, lineLevel) + else: + print linein.strip(), + else: + print "
    " + print linein.strip(), + print "
    \n" + else: + if (lineLevel == linein.find(" ") + 1) or \ + (lineLevel == linein.find(":") + 1): + if (inBodyText == 0): + handleBodyText(linein, lineLevel) + else: + print linein.strip(), + else: + if (inBodyText == 1): + print"

    " + inBodyText = 0 + print "" + linein.strip(), + + +# flatten +# Flatten a subsection of an outline. The index passed is the +# outline section title. All sublevels that are only one level +# deeper are indcluded in the current subsection. Then there is +# a recursion for those items listed in the subsection. Exits +# when the next line to be processed is of the same or lower +# outline level. (lower means shallower) +# input: idx - the index into the outline. The indexed line is the title. +# output: adds reformatted lines to flatoutline[] +def flatten(idx): + if (outline[idx] == ""): + return + if (len(outline) <= idx): + return + titleline = outline[idx] + titlelevel = getLineLevel(titleline) + if (getLineLevel(outline[idx + 1]) > titlelevel): + if (titleline[titlelevel - 1] != " "): + flatoutline.append(titleline.lstrip()) + exitflag = 0 + while (exitflag == 0): + if (idx < len(outline) - 1): + idx = idx + 1 + currlevel = getLineLevel(outline[idx]) + if (currlevel == titlelevel + 1): + if (currlevel == outline[idx].find(" ") + 1): + flatoutline.append("\t " + outline[idx].lstrip()) + else: + flatoutline.append("\t" + outline[idx].lstrip()) + elif (currlevel <= titlelevel): + exitflag = 1 + else: + exitflag = 1 + # level = titlelevel # FIXME level assigned but never used + return + + +def createCSS(): + global styleSheet + output = """ /* copyright notice and filename */ + body { + font-family: helvetica, arial, sans-serif; + font-size: 10pt; + } + /* title at the top of the page */ + H1 { + font-family: helvetica, arial, sans-serif; + font-size: 14pt; + font-weight: bold; + text-align: center; + color: black; + background-color: #ddddee; + padding-top: 20px; + padding-bottom: 20px; + } + H2 { + font-family: helvetica, arial, sans-serif; + font-size: 12pt; + font-weight: bold; + text-align: left; + color: black; + } + H3 { + font-family: helvetica, arial, sans-serif; + font-size: 12pt; + text-align: left; + color: black; + } + H4 { + font-family: helvetica, arial, sans-serif; + font-size: 12pt; + text-align: left; + color: black; + } + H5 { + font-family: helvetica, arial, sans-serif; + font-size: 10pt; + text-align: left; + color: black; + } + /* outline level spacing */ + OL { + margin-left: 1.0em; + padding-left: 0; + padding-bottom: 8pt; + } + /* global heading settings */ + LI { + font-family: helvetica, arial, sans-serif; + color: black; + font-weight: normal; + list-style: lower-alpha; + padding-top: 4px; + } + /* level 1 heading overrides */ + LI.L1 { + font-size: 12pt; + font-weight: bold; + list-style: none; + } + /* level 2 heading overrides */ + LI.L2 { + font-size: 10pt; + font-weight: bold; + list-style: none; + } + /* level 3 heading overrides */ + LI.L3 { + font-size: 10pt; + list-style: none; + } + /* level 4 heading overrides */ + LI.L4 { + font-size: 10pt; + list-style: none; + } + /* level 5 heading overrides */ + LI.L5 { + font-size: 10pt; + list-style: none; + } + /* level 6 heading overrides */ + LI.L6 { + font-size: 10pt; + list-style: none; + } + /* level 7 heading overrides */ + LI.L7 { + font-size: 10pt; + list-style: none; + } + /* level 1 bullet heading overrides */ + LI.LB1 { + font-size: 12pt; + font-weight: bold; + list-style: disc; + } + /* level 2 bullet heading overrides */ + LI.LB2 { + font-size: 10pt; + font-weight: bold; + list-style: disc; + } + /* level 3 bullet heading overrides */ + LI.LB3 { + font-size: 10pt; + list-style: disc; + } + /* level 4 bullet heading overrides */ + LI.LB4 { + font-size: 10pt; + list-style: disc; + } + /* level 5 bullet heading overrides */ + LI.LB5 { + font-size: 10pt; + list-style: disc; + } + /* level 6 bullet heading overrides */ + LI.LB6 { + font-size: 10pt; + list-style: disc; + } + /* level 7 bullet heading overrides */ + LI.LB7 { + font-size: 10pt; + list-style: disc; + } + /* level 1 numeric heading overrides */ + LI.LN1 { + font-size: 12pt; + font-weight: bold; + list-style: decimal; + } + /* level 2 numeric heading overrides */ + LI.LN2 { + font-size: 10pt; + font-weight: bold; + list-style: decimal; + } + /* level 3 numeric heading overrides */ + LI.LN3 { + font-size: 10pt; + list-style: decimal; + } + /* level 4 numeric heading overrides */ + LI.LN4 { + font-size: 10pt; + list-style: decimal; + } + /* level 5 numeric heading overrides */ + LI.LN5 { + font-size: 10pt; + list-style: decimal; + } + /* level 6 numeric heading overrides */ + LI.LN6 { + font-size: 10pt; + list-style: decimal; + } + /* level 7 numeric heading overrides */ + LI.LN7 { + font-size: 10pt; + list-style: decimal; + } + /* body text */ + P { + font-family: helvetica, arial, sans-serif; + font-size: 9pt; + font-weight: normal; + color: darkgreen; + } + /* preformatted text */ + PRE { + font-family: fixed, monospace; + font-size: 9pt; + font-weight: normal; + color: darkblue; + } + + TABLE { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 12pt; + font-weight: normal; + border-collapse: collapse; + } + + TH { + border: 1px solid black; + padding: 0.5em; + background-color: #eeddee; + } + + TD { + border: 1px solid black; + padding: 0.5em; + background-color: #ddeeee; + } + + CODE { + background-color: yellow; + } + + TABLE.TAB1 { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 12pt; + font-weight: normal; + border-collapse: collapse; + } + TABLE.TAB2 { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 11pt; + font-weight: normal; + border-collapse: collapse; + } + TABLE.TAB3 { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; + } + TABLE.TAB4 { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; + } + TABLE.TAB5 { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; + } + TABLE.TAB6 { + margin-top: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; + """ + file = open(styleSheet, "w") + file.write(output) + + +def printHeader(linein): + global styleSheet, inlineStyle + print """ + """ + getTitleText(linein) + "" + try: + file = open(styleSheet, "r") + except IOError: + createCSS() + file = open(styleSheet, "r") + if (styleSheet != "" and inlineStyle == 0): + print "" + if (styleSheet != "" and inlineStyle == 1): + print "" + print "" + + +def printFirstLine(linein): + print '''
    +

    %s

    +
    +
    ''' % stripTitleText(linein.strip()) + + +def printFooter(): + global slides, div + print "
    " + if (slides == 0 and div == 0): + print "
    " + print "
    " + print copyright + print "
    " + print inputFile + "   " + \ + time.strftime("%Y/%m/%d %H:%M", time.localtime(time.time())) + print "
    " + print "" + + +def main(): + global showTitle + getArgs() + file = open(inputFile, "r") + if (slides == 0): + firstLine = beautifyLine(file.readline().strip()) + printHeader(firstLine) + if (showTitle == 1): + printFirstLine(firstLine) + linein = beautifyLine(file.readline().strip()) + else: + linein = firstLine + while linein != "": + processLine(linein) + linein = file.readline() + closeLevels() + else: + linein = beautifyLine(file.readline().strip()) + outline.append(linein) + linein = file.readline().strip() + while linein != "": + outline.append("\t" + linein) + linein = file.readline().rstrip() + for i in range(0, len(outline) - 1): + flatten(i) + printHeader(flatoutline[0]) + for i in range(0, len(flatoutline)): + processLine(flatoutline[i]) + + printFooter() + file.close() + + +if __name__ == "__main__": + main() diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_autonumbered.css b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_autonumbered.css new file mode 100644 index 0000000..ddc8830 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_autonumbered.css @@ -0,0 +1,269 @@ + /* copyright notice and filename */ +body { + font-family: helvetica,arial,sans-serif; + font-size: 10pt; +} + /* title at the top of the page */ +H1 { + font-family: helvetica,arial,sans-serif; + font-size: 14pt; + font-weight: bold; + text-align: center; + color: black; + background-color: #ddddee; + padding-top: 20px; + padding-bottom: 20px; +} +H2 { + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + font-weight: bold; + text-align: left; + color: black; +} +H3 { + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + text-align: left; + color: black; +} +H4 { + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + text-align: left; + color: black; +} +H5 { + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + text-align: left; + color: black; +} + /* outline level spacing */ +OL { + padding-bottom: 8pt; + counter-reset: section; + margin-left: 1.0em; + padding-left:0 ; +} +OL LI { counter-increment: section; } +OL LI:before { content: counters(section, ".") ". "; } + /* global heading settings */ +LI { + font-family: helvetica,arial,sans-serif; + color: black; + font-weight: normal; + list-style: lower-alpha; + padding-top: 4px; +} + /* level 1 heading overrides */ +LI.L1 { + font-size: 12pt; + font-weight: bold; + list-style: none; +} + /* level 2 heading overrides */ +LI.L2 { + font-size: 10pt; + font-weight: bold; + list-style: none; +} + /* level 3 heading overrides */ +LI.L3 { + font-size: 10pt; + list-style: none; +} + /* level 4 heading overrides */ +LI.L4 { + font-size: 10pt; + list-style: none; +} + /* level 5 heading overrides */ +LI.L5 { + font-size: 10pt; + list-style: none; +} + /* level 6 heading overrides */ +LI.L6 { + font-size: 10pt; + list-style: none; +} + /* level 7 heading overrides */ +LI.L7 { + font-size: 10pt; + list-style: none; +} + /* level 8 heading overrides */ +LI.L8 { + font-size: 10pt; + list-style: none; +} + /* level 9 heading overrides */ +LI.L9 { + font-size: 10pt; + list-style: none; +} + /* level 10 heading overrides */ +LI.L10 { + font-size: 10pt; + list-style: none; +} + /* level 11 heading overrides */ +LI.L11 { + font-size: 10pt; + list-style: none; +} + /* level 1 bullet heading overrides */ +LI.LB1 { + font-size: 12pt; + font-weight: bold; + list-style: disc; +} + /* level 2 bullet heading overrides */ +LI.LB2 { + font-size: 10pt; + font-weight: bold; + list-style: disc; +} + /* level 3 bullet heading overrides */ +LI.LB3 { + font-size: 10pt; + list-style: disc; +} + /* level 4 bullet heading overrides */ +LI.LB4 { + font-size: 10pt; + list-style: disc; +} + /* level 5 bullet heading overrides */ +LI.LB5 { + font-size: 10pt; + list-style: disc; +} + /* level 6 bullet heading overrides */ +LI.LB6 { + font-size: 10pt; + list-style: disc; +} + /* level 7 bullet heading overrides */ +LI.LB7 { + font-size: 10pt; + list-style: disc; +} + /* level 1 numeric heading overrides */ +LI.LN1 { + font-size: 12pt; + font-weight: bold; + list-style: decimal; +} + /* level 2 numeric heading overrides */ +LI.LN2 { + font-size: 10pt; + font-weight: bold; + list-style: decimal; +} + /* level 3 numeric heading overrides */ +LI.LN3 { + font-size: 10pt; + list-style: decimal; +} + /* level 4 numeric heading overrides */ +LI.LN4 { + font-size: 10pt; + list-style: decimal; +} + /* level 5 numeric heading overrides */ +LI.LN5 { + font-size: 10pt; + list-style: decimal; +} + /* level 6 numeric heading overrides */ +LI.LN6 { + font-size: 10pt; + list-style: decimal; +} + /* level 7 numeric heading overrides */ +LI.LN7 { + font-size: 10pt; + list-style: decimal; +} + /* body text */ +P { + font-family: helvetica,arial,sans-serif; + font-size: 9pt; + font-weight: normal; + color: black; +} + /* preformatted text */ +PRE { + font-family: fixed,monospace; + font-size: 9pt; + font-weight: normal; + color: darkblue; +} + +TABLE { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + font-weight: normal; + border-collapse: collapse; +} + +TH { + border: 1px solid black; + padding: 0.5em; + background-color: #eeddee; +} + +TD { + border: 1px solid black; + padding: 0.5em; + background-color: #ddeeee; +} + +CODE { + background-color: yellow; +} + +TABLE.TAB1 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB2 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 11pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB3 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB4 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB5 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB6 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_nnnnnn.css b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_nnnnnn.css new file mode 100644 index 0000000..7405843 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2html_nnnnnn.css @@ -0,0 +1,246 @@ + /* copyright notice and filename */ +body { + font-family: helvetica,arial,sans-serif; + font-size: 10pt; +} + /* title at the top of the page */ +H1 { + font-family: helvetica,arial,sans-serif; + font-size: 14pt; + font-weight: bold; + text-align: center; + color: black; + background-color: #ddddee; + padding-top: 20px; + padding-bottom: 20px; +} +H2 { + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + font-weight: bold; + text-align: left; + color: black; +} +H3 { + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + text-align: left; + color: black; +} +H4 { + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + text-align: left; + color: black; +} +H5 { + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + text-align: left; + color: black; +} + /* outline level spacing */ +OL { + margin-left: 1.0em; + padding-left: 0; + padding-bottom: 8pt; +} + /* global heading settings */ +LI { + font-family: helvetica,arial,sans-serif; + color: black; + font-weight: normal; + list-style: lower-alpha; + padding-top: 4px; +} + /* level 1 heading overrides */ +LI.L1 { + font-size: 12pt; + font-weight: bold; + list-style: none; +} + /* level 2 heading overrides */ +LI.L2 { + font-size: 10pt; + font-weight: bold; + list-style: none; +} + /* level 3 heading overrides */ +LI.L3 { + font-size: 10pt; + list-style: none; +} + /* level 4 heading overrides */ +LI.L4 { + font-size: 10pt; + list-style: none; +} + /* level 5 heading overrides */ +LI.L5 { + font-size: 10pt; + list-style: none; +} + /* level 6 heading overrides */ +LI.L6 { + font-size: 10pt; + list-style: none; +} + /* level 7 heading overrides */ +LI.L7 { + font-size: 10pt; + list-style: none; +} + /* level 1 bullet heading overrides */ +LI.LB1 { + font-size: 12pt; + font-weight: bold; + list-style: disc; +} + /* level 2 bullet heading overrides */ +LI.LB2 { + font-size: 10pt; + font-weight: bold; + list-style: disc; +} + /* level 3 bullet heading overrides */ +LI.LB3 { + font-size: 10pt; + list-style: disc; +} + /* level 4 bullet heading overrides */ +LI.LB4 { + font-size: 10pt; + list-style: disc; +} + /* level 5 bullet heading overrides */ +LI.LB5 { + font-size: 10pt; + list-style: disc; +} + /* level 6 bullet heading overrides */ +LI.LB6 { + font-size: 10pt; + list-style: disc; +} + /* level 7 bullet heading overrides */ +LI.LB7 { + font-size: 10pt; + list-style: disc; +} + /* level 1 numeric heading overrides */ +LI.LN1 { + font-size: 12pt; + font-weight: bold; + list-style: decimal; +} + /* level 2 numeric heading overrides */ +LI.LN2 { + font-size: 10pt; + font-weight: bold; + list-style: decimal; +} + /* level 3 numeric heading overrides */ +LI.LN3 { + font-size: 10pt; + list-style: decimal; +} + /* level 4 numeric heading overrides */ +LI.LN4 { + font-size: 10pt; + list-style: decimal; +} + /* level 5 numeric heading overrides */ +LI.LN5 { + font-size: 10pt; + list-style: decimal; +} + /* level 6 numeric heading overrides */ +LI.LN6 { + font-size: 10pt; + list-style: decimal; +} + /* level 7 numeric heading overrides */ +LI.LN7 { + font-size: 10pt; + list-style: decimal; +} + /* body text */ +P { + font-family: helvetica,arial,sans-serif; + font-size: 9pt; + font-weight: normal; + color: darkgreen; +} + /* preformatted text */ +PRE { + font-family: fixed,monospace; + font-size: 9pt; + font-weight: normal; + color: darkblue; +} + +TABLE { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + font-weight: normal; + border-collapse: collapse; +} + +TH { + border: 1px solid black; + padding: 0.5em; + background-color: #eeddee; +} + +TD { + border: 1px solid black; + padding: 0.5em; + background-color: #ddeeee; +} + +CODE { + background-color: yellow; +} + +TABLE.TAB1 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 12pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB2 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 11pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB3 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB4 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB5 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; +} +TABLE.TAB6 { + margin-top: 1em; + font-family: helvetica,arial,sans-serif; + font-size: 10pt; + font-weight: normal; + border-collapse: collapse; diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/.vimrc b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/.vimrc new file mode 100644 index 0000000..d1675e5 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/.vimrc @@ -0,0 +1,44 @@ +" local .vimrc for working with otl2latex +" +" Used to write notes in vim outlier file (.otl) and have dynamically +" generated beamer-latex files produced. +" +" requires the script otl2latex.py is in the same directory as this script. +" also requires that your user ~/.vimrc file has "set exrc" specified +" +" This can be added to as more functionality is desired. +" +" Author: Serge Rey +" Last Revision: 2007-01-21 + +version 6.0 + +"get rid of blank lines +map ,n :g/^$/d + +"make the next paragraph a text block (in Vim Outliner terms) +map ,t ma}k^mb'a'bI| + +"make an itemized list out of the following contiguous lines (each line is an +"item) +map ,i ^ma}k^mb'a'bI\item 'aObegin{itemize}'aki\'bo\end{itemize} + +"make an itemized list out of the following contiguous lines (each line is an +"item) and then mark block as otl text +map ,I ^ma}k^mb'a'bI\item 'aObegin{itemize}'aki\'bo\end{itemize}'akma}k^mb'a'bI| + +map ,f ^Obegin{center}jo\end{center}k^i\includegraphics[width=.8\linewidth]{A}k^i\^jjmbkk'bI| + +"process the otl file to produce a pdf presentation +map ,b :!python otl2latex.py -p % %<.tex;pdflatex %<.tex  + +"pdflatex the current buffer +map ,p :!pdflatex % + +"set up menus +amenu o&2l.&process,b ,b +amenu o&2l.&delete\ blank\ lines,n ,n +amenu o2l.-Sep- : +amenu o&2l.&itemize,i ,i +amenu o&2l.&textualize,t ,t +amenu o&2l.&itemize_and_textualize,t ,I diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/README b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/README new file mode 100644 index 0000000..eb96167 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/README @@ -0,0 +1,23 @@ +otl2latex + +Translate a Vim Outliner file to a LaTeX document. + +Author: Serge Rey +Version 0.1 (2007-01-21) + +REQUIREMENTS + The Vim Outliner http://bike-nomad.com/vim/vimoutliner.html + beamer http://latex-beamer.sourceforge.net/ + Python http://www.python.org + + +INSTRUCTIONS +The user's guide is in otl2latex.pdf + +To reproduce it: + python otl2latex.py -p otl2latex.otl otl2latex.tex + pdflatex otl2latex + +DEVELOPMENT + otl2latex development is hosted at: + http://http://code.google.com/p/otl2latex/ diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.otl new file mode 100644 index 0000000..3333e9f --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.otl @@ -0,0 +1,95 @@ +preamble + @author Serge Rey + @institute sjsrey@gmail.com + @instituteShort sjsrey@gmail.com + @title otl2latex + @subtitle User's Guide + @titleShort http://code.google.com/p/otl2latex/ + @date November 3, 2007 + @dateShort otl2latex +Introduction + What is otl2latex? + Translator + otl to tex + |otl2latex allows you to + |* prepare your document in a powerful outliner + |* generate \LaTeX\ markup of your content + Requirements + Operating Systems + Operating Systems Supported + |otl2latex has been used successfully on + |* Linux + |* Mac OS X + |* Windows + Software Required + Packages and Programs + |* Python http://www.python.org + |* \LaTeX + |* Beamer http://latex-beamer.sourceforge.net/ + |* The Vim Outliner http://bike-nomad.com/vim/vimoutliner.html +Usage + Basics + Usage + From the command line + | \texttt{python otl2latex.py -p filename.otl filename.tex} + | + Notes + |* \texttt{filename.tex} will be generated, you don't edit that one. + |* You can run all this from withing Vim (see Vim Mappings below). + Basics + Presentations/Beamer + |* Level 1 in the outline become sections + |* Level 2 in the outline become subsections + |* Level 3 in the outline become frame titles + |* Level 4 in the outline become block titles + |* Text in the outline is treated as \LaTeX\ markup + Using Bullets + | Placing a '*' at the begining of a line will tell otl2latex to begin an itemize list. otl2latex currently supports 3 levels of Itemization. + |* First Level + |** Second Level + |*** Third Level + |** Second Level + Advanced + Tips + |* Level 4 can be omitted + |* You will have no blocks on that frame + Vim mappings + Vim Mappings: .vimrc + Processing + |* ,b will generate a pdf file from your outline + |* ,nb will remove all empty lines in your otl file + |* ,p will run the current vim buffer through pdflatex + Vim Mappings: .vimrc + Lists + |* ,i on the first line will create an itemized list of a block of lines + |* ,t will mark a block as otl text + |* ,I itemize and mark block as otl text + |You need to have a blank line at the end of the block to apply these. + Vim Mappings: .vimrc + Figures + |\begin{itemize} + |\item ,f (insert mode) will generate stub for figures + |\end{itemize} + A figure + | \begin{center} + | \includegraphics[width=.8\linewidth]{otl2latex.png} + | \end{center} + A figure + |\begin{center} + |\includegraphics[width=.8\linewidth]{otl2latex.png} + |\end{center} + Future Extensions + Move to vim script + .vimrc to otl2latex.vim + |\begin{itemize} + |\item Currently we are just embedding mappings in .vimrc + |\item Ok for testing, not very polished for end user + |\end{itemize} + Reverse Engineering + latex2otl + |\begin{itemize} + |\item take a tex file + |\item generate the otl file + |\end{itemize} + + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.pdf b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1c4d56a6cd3b60294e817fe90c0ac604eb6cc59f GIT binary patch literal 102839 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�k&5d&YGSe+k$Yk2`MOexh%7BF`r6 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 Mvu&H2t~$^E0Y|6Z_5c6? literal 0 HcmV?d00001 diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.png b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.png new file mode 100644 index 0000000000000000000000000000000000000000..a1622baafb6b44b023792fd090f38d0ebfb7f71f GIT binary patch literal 42112 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 +Version 0.1 (2007-01-21) +""" + +import os,sys + +class Line: + """Class for markup lines""" + def __init__(self, content): + ntabs=content.count("\t") + content=content.lstrip("\t") + level = ntabs - content.count("\t") + self.level=level + self.content = content + self.markup=0 + if content[0]=="|": + self.markup=1 + +#3 lines added here + self.bullet=0 + if len(content) > 2 and (content[2]=='*' or content[1]=='*'): + self.bullet=1 + #print "%d: %s"%(self.bullet,content) + +class Manager: + """Abstract class for LaTeX document classes""" + def __init__(self, content, fileOut): + self.content=content + self.fileOut=open(fileOut,'w') + self.parse() + self.fileOut.write(self.markup) + self.fileOut.close() + def parse(self): + self.lines=[ Line(line) for line in self.content] + preambleStart=0 + nl=len(self.lines) + id=zip(range(nl),self.lines) + level1=[i for i,line in id if line.level==0] + preambleEnd=level1[1] + preamble=self.lines[0:preambleEnd] + self.level1=level1 + preambleMarkup=[] + for line in preamble: + if line.content.count("@"): + tmp=line.content.split("@")[1] + tmp=tmp.split() + env=tmp[0] + content=" ".join(tmp[1:]) + mu="\\%s{%s}"%(env,content) + preambleMarkup.append(mu) + self.preamble=preambleMarkup + self.preambleLines=preamble + self.documentLines=self.lines[preambleEnd:] + + + + + +class Beamer(Manager): + """Manager for Beamer document class""" + def __init__(self, content,fileOut): + self.top1=""" +\documentclass[nototal,handout]{beamer} +\mode +{ + \usetheme{Madrid} + \setbeamercovered{transparent} +} + +\usepackage{verbatim} +\usepackage{fancyvrb} +\usepackage[english]{babel} +\usepackage[latin1]{inputenc} +\usepackage{times} +\usepackage{tikz} +\usepackage[T1]{fontenc} +\usepackage{graphicx} %sjr added +\graphicspath{{figures/}} +\usepackage{hyperref}""" + self.top2=""" +% Delete this, if you do not want the table of contents to pop up at +% the beginning of each subsection: +\AtBeginSubsection[] +{ + \\begin{frame} + \\frametitle{Outline} + \\tableofcontents[currentsection,currentsubsection] + \end{frame} +} + + +% If you wish to uncover everything in a step-wise fashion, uncomment +% the following command: +\\beamerdefaultoverlayspecification{<+->} +\\begin{document} +\\begin{frame} + \\titlepage +\end{frame} +\\begin{frame} + \\frametitle{Outline} + \\tableofcontents[pausesections] + % You might wish to add the option [pausesections] +\end{frame} +""" + self.bulletLevel = 0 + Manager.__init__(self, content, fileOut) + + def itemize(self,line): + nstars=line.content.count("*") + content=line.content.lstrip("|").lstrip().lstrip("*") + self.currentBLevel = nstars - content.count("*") + stuff=[] + if self.currentBLevel == self.bulletLevel and line.bullet: + mu='\\item '+line.content.lstrip("|").lstrip().lstrip("*") + elif line.bullet and self.currentBLevel > self.bulletLevel: + self.bulletLevel += 1 + stuff.append("\\begin{itemize}\n") + mu='\\item '+line.content.lstrip("|").lstrip().lstrip("*") + elif self.currentBLevel < self.bulletLevel and line.bullet: + self.bulletLevel -= 1 + stuff.append("\\end{itemize}\n") + mu='\\item '+line.content.lstrip("|").lstrip().lstrip("*") + elif self.currentBLevel < self.bulletLevel: + self.bulletLevel -= 1 + stuff.append("\\end{itemize}\n") + mu=line.content.lstrip("|") + else: + panic() + return stuff,mu + + def parse(self): + Manager.parse(self) + #print self.content + #print self.lines + #print self.level1 + #for info in self.preamble: + # print info + + # do my own preamble + field=("author ","instituteShort ","dateShort ","date ","subtitle ", + "title ", "institute ", "titleShort ") + pattern=["@"+token for token in field] + f=zip(field,pattern) + d={} + for field,pattern in f: + t=[line.content for line in self.preambleLines if line.content.count(pattern)] + if t: + d[field]= t[0].split(pattern)[1].strip() + else: + d[field]="" + preamble="\n\n\\author{%s}\n"%d['author '] + preamble+="\\institute[%s]{%s}\n"%(d['instituteShort '],d['institute ']) + preamble+="\\title[%s]{%s}\n"%(d['titleShort '],d['title ']) + preamble+="\\subtitle{%s}\n"%(d['subtitle ']) + preamble+="\\date[%s]{%s}\n"%(d['dateShort '],d['date ']) + + print self.preamble + self.preamble=preamble + + + body=[] + prev=0 + frameOpen=0 + blockOpen=0 + frameCount=0 + blockCount=0 + + for line in self.documentLines: + if line.level==0: + for i in range(0,self.bulletLevel): + self.bulletLevel -= 1 + body.append("\\end{itemize}\n") + if blockOpen: + body.append("\\end{block}") + blockOpen=0 + if frameOpen: + body.append("\\end{frame}") + frameOpen=0 + mu="\n\n\n\\section{%s}"%line.content.strip() + elif line.level==1: + for i in range(0,self.bulletLevel): + self.bulletLevel -= 1 + body.append("\\end{itemize}\n") + if blockOpen: + body.append("\\end{block}") + blockOpen=0 + if frameOpen: + body.append("\\end{frame}") + frameOpen=0 + mu="\n\n\\subsection{%s}"%line.content.strip() + elif line.level==2: + # check if this frame has blocks or is nonblocked + if line.markup: + if line.bullet or self.bulletLevel: + stuff,mu=self.itemize(line) + if len(stuff) > 0: + for i in stuff: + body.append(i) + else: + mu=line.content.lstrip("|") + else: + for i in range(0,self.bulletLevel): + self.bulletLevel -= 1 + body.append("\\end{itemize}\n") + if blockOpen: + body.append("\\end{block}") + blockOpen=0 + if frameOpen: + body.append("\\end{frame}") + else: + frameOpen=1 + # check for verbatim here + tmp=line.content.strip() + if tmp.count("@vb"): + tmp=tmp.split("@")[0] + mu="\n\n\\begin{frame}[containsverbatim]\n\t\\frametitle{%s}\n"%tmp + else: + mu="\n\n\\begin{frame}\n\t\\frametitle{%s}\n"%tmp + frameCount+=1 + elif line.level==3: + # check if it is a block or body content + if line.markup: + if line.bullet or self.bulletLevel: + stuff,mu=self.itemize(line) + if len(stuff) > 0: + for i in stuff: + body.append(i) + else: + mu=line.content.lstrip("\t") + mu=mu.lstrip("|") + else: + for i in range(0,self.bulletLevel): + self.bulletLevel -= 1 + body.append("\\end{itemize}\n") + #block title + if blockOpen: + body.append("\\end{block}") + else: + blockOpen=1 + mu="\n\\begin{block}{%s}\n"%line.content.strip() + blockCount+=1 + else: + mu="" + body.append(mu) + for i in range(0,self.bulletLevel): + self.bulletLevel -= 1 + body.append("\\end{itemize}\n") + if blockOpen: + body.append("\\end{block}") + if frameOpen: + body.append("\\end{frame}") + + self.body=" ".join(body) + self.markup=self.top1+self.preamble+self.top2 + self.markup+=self.body + self.markup+="\n\\end{document}\n" + print self.markup + +# Process command line arguments +args = sys.argv +nargs=len(args) +dispatch={} +dispatch['beamer']=Beamer +inputFileName=None +outputFileName=None + +def printUsage(): + print usage + sys.exit() + +if nargs==1: + printUsage() +else: + docType='beamer' + options=args[1] + if options.count("-"): + if options.count("a"): + docType='article' + elif options.count("b"): + docType='book' + if nargs==2: + printUsage() + elif nargs==3: + inputFileName=args[2] + elif nargs==4: + inputFileName=args[2] + outputFileName=args[3] + else: + printUsage() + elif nargs==2: + inputFileName=args[1] + elif nargs==3: + inputFileName=args[1] + outputFileName=args[3] + else: + printUsage() + # Dispatch to correct document class manager + fin=open(inputFileName,'r') + content=fin.readlines() + fin.close() + dispatch[docType](content,outputFileName) diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.tex b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.tex new file mode 100644 index 0000000..31f4766 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.tex @@ -0,0 +1,223 @@ + +\documentclass[nototal,handout]{beamer} +\mode +{ + \usetheme{Madrid} + \setbeamercovered{transparent} +} + +\usepackage{verbatim} +\usepackage{fancyvrb} +\usepackage[english]{babel} +\usepackage[latin1]{inputenc} +\usepackage{times} +\usepackage{tikz} +\usepackage[T1]{fontenc} +\usepackage{graphicx} %sjr added +\graphicspath{{figures/}} +\usepackage{hyperref} + +\author{Serge Rey} +\institute[sjsrey@gmail.com]{sjsrey@gmail.com} +\title[http://code.google.com/p/otl2latex/]{otl2latex} +\subtitle{User's Guide} +\date[otl2latex]{November 3, 2007} + +% Delete this, if you do not want the table of contents to pop up at +% the beginning of each subsection: +\AtBeginSubsection[] +{ + \begin{frame} + \frametitle{Outline} + \tableofcontents[currentsection,currentsubsection] + \end{frame} +} + + +% If you wish to uncover everything in a step-wise fashion, uncomment +% the following command: +\beamerdefaultoverlayspecification{<+->} +\begin{document} +\begin{frame} + \titlepage +\end{frame} +\begin{frame} + \frametitle{Outline} + \tableofcontents[pausesections] + % You might wish to add the option [pausesections] +\end{frame} + + + +\section{Introduction} + +\subsection{What is otl2latex?} + +\begin{frame} + \frametitle{Translator} + +\begin{block}{otl to tex} + otl2latex allows you to + \begin{itemize} + \item prepare your document in a powerful outliner + \item generate \LaTeX\ markup of your content + \end{itemize} + \end{block} \end{frame} + +\subsection{Requirements} + +\begin{frame} + \frametitle{Operating Systems} + +\begin{block}{Operating Systems Supported} + otl2latex has been used successfully on + \begin{itemize} + \item Linux + \item Mac OS X + \item Windows + \end{itemize} + \end{block} \end{frame} + +\begin{frame} + \frametitle{Software Required} + +\begin{block}{Packages and Programs} + \begin{itemize} + \item Python http://www.python.org + \item \LaTeX + \item Beamer http://latex-beamer.sourceforge.net/ + \item The Vim Outliner http://bike-nomad.com/vim/vimoutliner.html + \end{itemize} + \end{block} \end{frame} + + +\section{Usage} + +\subsection{Basics} + +\begin{frame} + \frametitle{Usage} + +\begin{block}{From the command line} + \texttt{python otl2latex.py -p filename.otl filename.tex} + + \end{block} +\begin{block}{Notes} + \begin{itemize} + \item \texttt{filename.tex} will be generated, you don't edit that one. + \item You can run all this from withing Vim (see Vim Mappings below). + \end{itemize} + \end{block} \end{frame} + +\begin{frame} + \frametitle{Basics} + +\begin{block}{Presentations/Beamer} + \begin{itemize} + \item Level 1 in the outline become sections + \item Level 2 in the outline become subsections + \item Level 3 in the outline become frame titles + \item Level 4 in the outline become block titles + \item Text in the outline is treated as \LaTeX\ markup + \end{itemize} + \end{block} +\begin{block}{Using Bullets} + Placing a '*' at the begining of a line will tell otl2latex to begin an itemize list. otl2latex currently supports 3 levels of Itemization. + \begin{itemize} + \item First Level + \begin{itemize} + \item Second Level + \begin{itemize} + \item Third Level + \end{itemize} + \item Second Level + \end{itemize} + \end{itemize} + \end{block} \end{frame} + +\begin{frame} + \frametitle{Advanced} + +\begin{block}{Tips} + \begin{itemize} + \item Level 4 can be omitted + \item You will have no blocks on that frame + \end{itemize} + \end{block} \end{frame} + +\subsection{Vim mappings} + +\begin{frame} + \frametitle{Vim Mappings: .vimrc} + +\begin{block}{Processing} + \begin{itemize} + \item ,b will generate a pdf file from your outline + \item ,nb will remove all empty lines in your otl file + \item ,p will run the current vim buffer through pdflatex + \end{itemize} + \end{block} \end{frame} + +\begin{frame} + \frametitle{Vim Mappings: .vimrc} + +\begin{block}{Lists} + \begin{itemize} + \item ,i on the first line will create an itemized list of a block of lines + \item ,t will mark a block as otl text + \item ,I itemize and mark block as otl text + \end{itemize} + You need to have a blank line at the end of the block to apply these. + \end{block} \end{frame} + +\begin{frame} + \frametitle{Vim Mappings: .vimrc} + +\begin{block}{Figures} + \begin{itemize} + \item ,f (insert mode) will generate stub for figures + \end{itemize} + \end{block} \end{frame} + +\begin{frame} + \frametitle{A figure} + \begin{center} + \includegraphics[width=.8\linewidth]{otl2latex.png} + \end{center} + \end{frame} + +\begin{frame} + \frametitle{A figure} + \begin{center} + \includegraphics[width=.8\linewidth]{otl2latex.png} + \end{center} + \end{frame} + +\subsection{Future Extensions} + +\begin{frame} + \frametitle{Move to vim script} + +\begin{block}{.vimrc to otl2latex.vim} + \begin{itemize} + \item Currently we are just embedding mappings in .vimrc + \item Ok for testing, not very polished for end user + \end{itemize} + \end{block} \end{frame} + +\begin{frame} + \frametitle{Reverse Engineering} + +\begin{block}{latex2otl} + \begin{itemize} + \item take a tex file + \item generate the otl file + \end{itemize} + \end{block} \end{frame} + + +\section{} + + +\section{} +\end{document} diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.toc b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.toc new file mode 100644 index 0000000..ae333f6 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2latex/otl2latex.toc @@ -0,0 +1,9 @@ +\beamer@endinputifotherversion {3.07pt} +\select@language {english} +\beamer@sectionintoc {1}{Introduction}{3}{0}{1} +\beamer@subsectionintoc {1}{1}{What is otl2latex?}{3}{0}{1} +\beamer@subsectionintoc {1}{2}{Requirements}{4}{0}{1} +\beamer@sectionintoc {2}{Usage}{6}{0}{2} +\beamer@subsectionintoc {2}{1}{Basics}{6}{0}{2} +\beamer@subsectionintoc {2}{2}{Vim mappings}{9}{0}{2} +\beamer@subsectionintoc {2}{3}{Future Extensions}{14}{0}{2} diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2lyx.awk b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2lyx.awk new file mode 100644 index 0000000..cc6e381 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2lyx.awk @@ -0,0 +1,149 @@ +#!/usr/bin/gawk -f + +# Copyright (C) 2007 by Steve Litt, all rights reserved. +# Licensed under the GNU General Public License, version 2. +# otl2lyx.awk version 0.1.1 pre-alpha +# 4/23/2007 +# Fixed insertion of other environments at bodytext to bodytext +# borders. +# +# USAGE: ./otl2lyx level-environment-table-file outline-file +# +# level-table-structure: +# 1: Top-level-environment-name +# 2: 2nd-level-environment-name +# 3: 3rd-level-environment-name +# 4: 4th-level-environment-name +# 5: 5th-level-environment-name +# 6: 6th-level-environment-name +# bodytext: environment-name-for-normal-text +# +# Example for a book: +# 1: Chapter +# 2: Section +# 3: Subsection +# 4: Subsubsection +# 5: Paragraph +# 6: Subparagraph +# 7: Garbage7 +# bodytext: Standard + + +BEGIN{ + FS=":[ \t]*" + OFS="\x09" + lastinbodytext=0 +} + +### BLOW OFF BLANKS OUTSIDE OF BODY TEXT +$0~/^[ \t]*$/ && inbodytext==0{ + next +} + +### FILL THE ENVIRONMENTS ARRAY ### +ARGIND==1{ + FS=":[ \t]*"; + sub(/[ \t]*$/,"",$2); + environments[$1] = $2; + next; +} + +FNR==101{ + for(i in environments) print "level=" i ", string=" environments[i]; +} + +### FIELD SEPARATOR IS TAB ON THE OUTLINE FILE ### +{FS="\x09"; } + +### INCREMENT OUTLINE ID NUMBER +{ol_id++} + +### CALCULATE LEVEL ### +{ + for(i=1;i<=NF;i++) + if($i == ""){ + } else { + break + } + this["level"] = i + if(ol_id == ol_id_first) + this["level"]-- +} + +### FIGURE TEXT ### +{ + this["text"] = "" + for(i=1;i<=NF;i++){ + if($i != ""){ + if(this["text"] == ""){ + this["text"] = this["text"] $i + } else { + this["text"] = this["text"] " " $i + } + } + } + sub(/^[ \t]+/, "", this["text"]); + sub(/[ \t]+$/, "", this["text"]); +} + +### SET BODYTEXT FLAGS ### +{ inbodytext = 0; newbodytext = 0; endbodytext = 0; btblankline=0; } + + +this["text"] ~ /^:[ \t]+[^ \t]/{ + inbodytext = 1; + sub(/^:[ \t]*/, "", this["text"]); + this["text"] = this["text"] " "; +} + +this["text"] == "" || this["text"] == ":"{ + this["text"] = ""; + inbodytext = lastinbodytext; + if(inbodytext == 1){ + endbodytext = 1; + newbodytext = 1; + btblankline = 1; + } +} + +lastinbodytext == 1 && inbodytext == 0{ + endbodytext = 1; +} + +lastinbodytext == 0 && inbodytext == 1{ + newbodytext = 1; +} + +{ lastinbodytext = inbodytext; } + + + +### QUOTE SINGLE BACKSLASHES FOR LATEX ### +{gsub(/\\/,"\r\\backslash\r", this["text"]);} + +### PRINT LYX CONTENT ### + +endbodytext == 1{ + print "\\end_layout" + print "" +} +newbodytext == 1{ + print "\\begin_layout " environments["bodytext"] +} +inbodytext == 1{ + if(btblankline == 0) print this["text"] +} + +inbodytext == 0{ + print "\\begin_layout " environments[this["level"]] + print this["text"] + print "\\end_layout" + print "" +} + +END{ + if(inbodytext == 1){ + print "\\end_layout" + print "" + } +} diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.py new file mode 100755 index 0000000..7d3ab67 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.py @@ -0,0 +1,263 @@ +#!/usr/bin/python2 +# otl2ooimpress.py +# needs otl2ooimpress.sh to work in an automated way +############################################################################# +# +# Tool for Vim Outliner files to Open Office Impress files. +# Copyright (C) 2003 by Noel Henson, all rights reserved. +# +# This tool is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, see +# . +# +############################################################################# +# ALPHA VERSION!!! + +########################################################################### +# Basic function +# +# This program accepts VO outline files and converts them +# to the zipped XML files required by Open Office Impress. +# +# 10 outline levels are supported. These loosely correspond to the +# HTML H1 through H9 tags. +# + + +########################################################################### +# include whatever mdules we need + +import sys +########################################################################### +# global variables + +level = 0 +inputFile = "" +outline = [] +flatoutline = [] +pageNumber = 0 +inPage = 0 +debug = 0 + +########################################################################### +# function definitions + + +# usage +# print the simplest form of help +# input: none +# output: simple command usage is printed on the console +def showUsage(): + print + print "Usage:" + print "otl2ooimpress.py [options] inputfile > outputfile" + print "" + print "output is on STDOUT" + print + + +# getArgs +# Check for input arguments and set the necessary switches +# input: none +# output: possible console output for help, switch variables may be set +def getArgs(): + global inputfile, debug + if (len(sys.argv) == 1): + showUsage() + sys.exit()() + else: + for i in range(len(sys.argv)): + if (i != 0): + if (sys.argv[i] == "-d"): + debug = 1 # test for debug flag + elif (sys.argv[i] == "-?"): # test for help flag + showUsage() # show the help + sys.exit() # exit + elif (sys.argv[i] == "--help"): + showUsage() + sys.exit() + elif (sys.argv[i] == "-h"): + showUsage() + sys.exit() + elif (sys.argv[i][0] == "-"): + print "Error! Unknown option. Aborting" + sys.exit() + else: # get the input file name + inputfile = sys.argv[i] + + +# getLineLevel +# get the level of the current line (count the number of tabs) +# input: linein - a single line that may or may not have tabs at the beginning +# output: returns a number 1 is the lowest +def getLineLevel(linein): + strstart = linein.lstrip() # find the start of text in line + x = linein.find(strstart) # find the text index in the line + n = linein.count("\t", 0, x) # count the tabs + return(n + 1) # return the count + 1 (for level) + + +# getLineTextLevel +# get the level of the current line (count the number of tabs) +# input: linein - a single line that may or may not have tabs at the beginning +# output: returns a number 1 is the lowest +def getLineTextLevel(linein): + strstart = linein.lstrip() # find the start of text in line + x = linein.find(strstart) # find the text index in the line + n = linein.count("\t", 0, x) # count the tabs + n = n + linein.count(" ", 0, x) # count the spaces + return(n + 1) # return the count + 1 (for level) + + +# colonStrip(line) +# stip a leading ':', if it exists +# input: line +# output: returns a string with a stipped ':' +def colonStrip(line): + if (line[0] == ":"): + return line[1:].lstrip() + else: + return line + + +# processLine +# process a single line +# input: linein - a single line that may or may not have tabs at the beginning +# level - an integer between 1 and 9 that show the current level +# (not to be confused with the level of the current line) +# output: through standard out +def processLine(linein): + global inPage, pageNumber + if (linein.lstrip() == ""): + print + return + if (getLineLevel(linein) == 1): + if (inPage == 1): + print '' + inPage = 0 + pageNumber += 1 + outstring = '' + print outstring + outstring = '' + print outstring + outstring = '' + outstring += linein.lstrip() + outstring += "" + print outstring + outstring = '' + print outstring + inPage = 1 + else: + outstring = '' + outstring += linein.lstrip() + outstring += '' + print outstring + + +# flatten +# Flatten a subsection of an outline. The index passed is the outline section +# title. All sublevels that are only one level deeper are indcluded in the +# current subsection. Then there is a recursion for those items listed in the +# subsection. Exits when the next line to be processed is of the same or lower +# outline level. +# (lower means shallower) +# input: idx - the index into the outline. The indexed line is the title. +# output: adds reformatted lines to flatoutline[] +def flatten(idx): + if (outline[idx] == ""): + return + if (len(outline) <= idx): + return + titleline = outline[idx] + titlelevel = getLineLevel(titleline) + if (getLineLevel(outline[idx + 1]) > titlelevel): + if (titleline[titlelevel - 1] != " "): + flatoutline.append(titleline.lstrip()) + exitflag = 0 + while (exitflag == 0): + if (idx < len(outline) - 1): + idx = idx + 1 + currlevel = getLineLevel(outline[idx]) + if (currlevel == titlelevel + 1): + if (currlevel == outline[idx].find(" ") + 1): + flatoutline.append("\t " + outline[idx].lstrip()) + else: + flatoutline.append("\t" + outline[idx].lstrip()) + elif (currlevel <= titlelevel): + exitflag = 1 + else: + exitflag = 1 + return + + +def printHeader(linein): + print''' + + + + ''' + + +def printFooter(): + print '' + print'' + + +def main(): + getArgs() + file = open(inputFile, "r") + linein = file.readline().strip() + outline.append(linein) + linein = file.readline().strip() + while linein != "": + outline.append("\t" + linein) + linein = file.readline().rstrip() + for i in range(0, len(outline) - 1): + flatten(i) + + printHeader(flatoutline[0]) + for i in range(0, len(flatoutline)): + processLine(flatoutline[i]) + printFooter() + + file.close() + +main() diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.sh b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.sh new file mode 100755 index 0000000..9e2432d --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2ooimpress.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# otl2ooimpress.sh +# needs otl2ooimpress.py to work at all +############################################################################# +# +# Tool for Vim Outliner files to Open Office Impress files. +# Copyright (C) 2003 by Noel Henson, all rights reserved. +# +# This tool is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, see +# . +# +############################################################################# + +# Path to otl2ooimpress.py +MYPATH=$HOME/bin +# Path to rm +RMPATH=/bin +# Path to zip +ZIPPATH=/usr/bin + +$MYPATH/otl2ooimpress.py $1 > content.xml +$ZIPPATH/zip $1.sxi content.xml +$RMPATH/rm content.xml diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2table.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2table.py new file mode 100755 index 0000000..543792b --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl2table.py @@ -0,0 +1,199 @@ +#!/usr/bin/python2 +# otl2table.py +# convert a tab-formatted outline from VIM to tab-delimited table +# +# Copyright (c) 2004 Noel Henson All rights reserved +# +# ALPHA VERSION!!! + +########################################################################### +# Basic function +# +# This program accepts text outline files and converts them +# the tab-delimited text tables. +# This: +# Test +# Dog +# Barks +# Howls +# Cat +# Meows +# Yowls +# Becomes this: +# Test Dog Barks +# Test Dog Howls +# Test Cat Meows +# Test Cat Yowls +# +# This will make searching for groups of data and report generation easier. +# + + +########################################################################### +# include whatever mdules we need + +import sys +from string import * +#from time import * + +########################################################################### +# global variables + +level = 0 +inputFile = "" +formatMode = "tab" +noTrailing = 0 +columns = [] + +########################################################################### +# function definitions + +# usage +# print the simplest form of help +# input: none +# output: simple command usage is printed on the console + +def showUsage(): + print + print "Usage:" + print "otl2table.py [options] inputfile > outputfile" + print "Options" + print " -n Don't include trailing columns." + print " -t type Specify field separator type." + print " Types:" + print " tab - separate fields with tabs (default)" + print " csv - separate fields with ," + print " qcsv - separate fields with \",\"" + print " bullets - uses HTML tags \n$in\n" ); + } + $r->print( "\n" ); + } + $r->print( "\n\n" ); + } + + my $t1 = Time::HiRes::gettimeofday; + my $td = sprintf("%0.3f", $t1 - $t0); + $r->print("
    OTL parsed in $td secs
    \n") if $opt{timer}; + $r->print(< + +EHTML + + return OK; +} + +sub sorter +{ + my ($opt, $re) = @_; + return 0 unless $opt->{sorttype}; + my ($sa, $sb); + if ($opt->{sorttype} eq 'percent') { + $sa = $2 if $a =~ $re->{percent}; + $sb = $2 if $b =~ $re->{percent}; + return $opt->{sortrev} ? $sb <=> $sa : $sa <=> $sb; + } + else { + $sa = $1 if $a =~ $re->{linetext}; + $sb = $1 if $b =~ $re->{linetext}; + return $opt->{sortrev} ? $sb cmp $sa : $sa cmp $sb; + } +} + +1; + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/README b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/README new file mode 100644 index 0000000..ddc610d --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/README @@ -0,0 +1,155 @@ + + WHAT IS THIS? +--------------------------------------------------------------------- + +Vimoutliner already comes with some otl to HTML converters that work +quite well. I maintain a few different otl files, that are displayed +on a internal intranet - the step of converting to HTML on every little +change before upload was becoming mildly irritating, and countering my +near legendary laziness. + +This mod_perl handler teaches apache how to pretty print otl natively. + +Now, I can just edit the otl files directly - skip the conversion step +altogether, and let Apache make some delicious looking outlines. + + + INSTALLATION +--------------------------------------------------------------------- + +First of all, prerequisites! + + - apache2 + - mod_perl2 + - libapreq2 (Apache2::Request) + +Add the following lines in your httpd.conf, or in a +separate otl.conf in the apache Includes directory: + + ------------------------- + PerlSwitches -I/path/to/perl/libraries + PerlModule Apache::OTL + + + SetHandler perl-script + PerlResponseHandler Apache::OTL + + ------------------------- + +Doublecheck that your apreq2 module is setup to load, as well. + +That's it. Apache will now pretty-print all your otl files. + + + SETTINGS +--------------------------------------------------------------------- + +Settings for the otl_handler are stored on the first line of the otl +files themselves, prefixed by the 'user no wrap' character, '<'. See +the sample.otl for an example settings line. All settings are entirely +optional. + +title + Type: string + Default: filename + + The title of the OTL. Used as a header, and the html title. + If this is not set, the html title is derived from the filename. + + +style + Type: string + Default: none + + A path to css style(s). + Comma separated values load different files in order. + Media type defaults to 'screen', if the css name contains the + string 'print' anywhere, the media type is changed to print. + + :style=/css/otl_style.css,/css/print_style.css + +js + Type: string + Default: none + + Use javascript? If set, loads an external javascript library. + Comma separated values load diff files in order. + + +last_mod + Type: boolean + Default: 0 + + Show modification time of the otl file? + + +legend + Type: boolean + Default: 0 + + Display small legend for todo and done items? + + +sort + Type: boolean + Default: 0 + + Show sort links? + + +sorttype + Type: string + Default: none + + Default sorting method. Valid values are + percent + alpha + + +sortrev + Type: boolean + Default: 0 + + Should we default to reverse sorting? + + +counts + Type: boolean + Default: 0 + + Count and display sub items? + + +timer + Type: boolean + Default: 0 + + Display how long the parser took to generate the html? + + + + INCLUDED FILES +--------------------------------------------------------------------- + +/Apache/OTL.pm + The mod_perl content handler. + +/javascript/* + Example (but functional!) javascript. Create line numbers, + various eye candies, and clickable folds. + + This requires the 'jquery.js' library, also included. + +/sample.otl + An example vimoutliner file, with optional settings. + +/styles/* + "Theme" examples for customizing OTL display. + + + ACKNOWLEDGEMENTS +--------------------------------------------------------------------- + +Thanks to Nathan Dabney and +Michael Granger for their help and advice! + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/devel-mode b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/devel-mode new file mode 100644 index 0000000..f77cf6a --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/devel-mode @@ -0,0 +1,5 @@ +PerlModule Apache2::Reload +PerlInitHandler Apache2::Reload +PerlSetVar ReloadAll Off +PerlSetVar ReloadModules "Apache::OTL" +PerlSetVar ReloadConstantRedefineWarnings Off diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/jquery.js b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/jquery.js new file mode 100644 index 0000000..4384f4c --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/jquery.js @@ -0,0 +1,12 @@ +/* + * jQuery 1.0.2 - New Wave Javascript + * + * Copyright (c) 2006 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2006-10-09 20:23:18 -0400 (Mon, 09 Oct 2006) $ + * $Rev: 1b5eb968d2c4 $ + */ + +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('l(1Y 1O.6=="P"){1O.P=1O.P;6=q(a,c){l(a&&1Y a=="q"&&6.C.1T)v 6(15).1T(a);a=a||6.1k||15;l(a.2J)v 6(6.1X(a,[]));l(c&&c.2J)v 6(c).2j(a);l(1O==7)v 1f 6(a,c);u m=/^[^<]*(<.+>)[^>]*$/.36(a);l(m)a=6.31([m[1]]);7.1o(a.N==2y||a.D&&!a.1S&&a[0]!=P&&a[0].1S?6.1X(a,[]):6.2j(a,c));u C=1d[1d.D-1];l(C&&1Y C=="q")7.U(C)};l(1Y $!="P")6.3W$=$;u $=6;6.C=6.89={2J:"1.0.2",4u:q(){v 7.D},1o:q(26){l(26&&26.N==2y){7.D=0;[].1l.17(7,26);v 7}F v 26==P?6.1X(7,[]):7[26]},U:q(C,1h){v 6.U(7,C,1h)},8b:q(16){u 2c=-1;7.U(q(i){l(7==16)2c=i});v 2c},1r:q(1P,W,B){v 1P.N!=1N||W!=P?7.U(q(){l(W==P)H(u I 1q 1P)6.1r(B?7.1a:7,I,1P[I]);F 6.1r(B?7.1a:7,1P,W)}):6[B||"1r"](7[0],1P)},1g:q(1P,W){v 7.1r(1P,W,"20")},2V:q(e){e=e||7;u t="";H(u j=0;j0:14},2K:q(1h,1p,2N,C){u 3G=7.4u()>1;u a=6.31(1h);v 7.U(q(){u 16=7;l(1p&&7.2x.2h()=="60"&&a[0].2x.2h()!="61"){u 25=7.4R("25");l(!25.D){16=15.4E("25");7.44(16)}F 16=25[0]}H(u i=(2N<0?a.D-1:0);i!=(2N<0?2N:a.D);i+=2N){C.17(16,[3G?a[i].3D(V):a[i]])}})},28:q(a,1h){u C=1h&&1h[1h.D-1];u 2i=1h&&1h[1h.D-2];l(C&&C.N!=1v)C=Q;l(2i&&2i.N!=1v)2i=Q;l(!C){l(!7.3d)7.3d=[];7.3d.1l(7.1o());7.1o(a)}F{u 1U=7.1o();7.1o(a);l(2i&&a.D||!2i)7.U(2i||C).1o(1U);F 7.1o(1U).U(C)}v 7}};6.1L=6.C.1L=q(16,I){l(!I){I=16;16=7}H(u i 1q I)16[i]=I[i];v 16};6.1L({5C:q(){6.63=V;6.U(6.2l.5u,q(i,n){6.C[i]=q(a){u K=6.2t(7,n);l(a&&a.N==1N)K=6.19(a,K).r;v 7.28(K,1d)}});6.U(6.2l.2q,q(i,n){6.C[i]=q(){u a=1d;v 7.U(q(){H(u j=0;j"}F l(!a[i].1c("<3v")){1p="3v";a[i]="<1p>"+a[i]+""}F l(!a[i].1c("<3M")||!a[i].1c("<6r")){1p="3M";a[i]="<1p><25><3v>"+a[i]+""}u 1F=15.4E("1F");1F.2u=a[i];l(1p){1F=1F.1M;l(1p!="4j")1F=1F.1M;l(1p=="3M")1F=1F.1M}H(u j=0;j<1F.2e.D;j++)r.1l(1F.2e[j])}F l(a[i].2J||a[i].D&&!a[i].1S)H(u k=0;km[3]-0",4J:"m[3]-0==i",5o:"m[3]-0==i",2f:"i==0",1R:"i==r.D-1",52:"i%2==0",53:"i%2","4J-32":"6.1x(a,m[3]).1m","2f-32":"6.1x(a,0).1m","1R-32":"6.1x(a,0).1R","6v-32":"6.1x(a).D==1",5v:"a.2e.D",5A:"!a.2e.D",5r:"(a.7L||a.2u).1c(m[3])>=0",6w:"a.B!=\'1V\'&&6.1g(a,\'1t\')!=\'21\'&&6.1g(a,\'4e\')!=\'1V\'",1V:"a.B==\'1V\'||6.1g(a,\'1t\')==\'21\'||6.1g(a,\'4e\')==\'1V\'",7I:"!a.2R",2R:"a.2R",34:"a.34",4f:"a.4f || 6.1r(a, \'4f\')",2V:"a.B==\'2V\'",5G:"a.B==\'5G\'",5H:"a.B==\'5H\'",4l:"a.B==\'4l\'",4L:"a.B==\'4L\'",4n:"a.B==\'4n\'",5I:"a.B==\'5I\'",4m:"a.B==\'4m\'",48:"a.B==\'48\'",5B:"a.2x.41().4U(/5B|5O|6C|48/)"},".":"6.1e.3l(a,m[2])","@":{"=":"z==m[4]","!=":"z!=m[4]","^=":"z && !z.1c(m[4])","$=":"z && z.2U(z.D - m[4].D,m[4].D)==m[4]","*=":"z && z.1c(m[4])>=0","":"z"},"[":"6.2j(m[2],a).D"},3j:["\\\\.\\\\.|/\\\\.\\\\.","a.1n",">|/","6.1x(a.1M)","\\\\+","6.1x(a).3p","~",q(a){u r=[];u s=6.1x(a);l(s.n>0)H(u i=s.n;i=1)t=t.2U(t.1c("/"),t.D)}u K=[1k];u 1J=[];u 1R=Q;2d(t.D>0&&1R!=t){u r=[];1R=t;t=6.2I(t).1A(/^\\/\\//i,"");u 3k=14;H(u i=0;i<6.3j.D;i+=2){l(3k)51;u 2o=1f 3T("^("+6.3j[i]+")");u m=2o.36(t);l(m){r=K=6.2t(K,6.3j[i+1]);t=6.2I(t.1A(2o,""));3k=V}}l(!3k){l(!t.1c(",")||!t.1c("|")){l(K[0]==1k)K.3O();1J=6.1X(1J,K);r=K=[1k];t=" "+t.2U(1,t.D)}F{u 3P=/^([#.]?)([a-4X-9\\\\*3W-]*)/i;u m=3P.36(t);l(m[1]=="#"){u 4q=15.5z(m[2]);r=K=4q?[4q]:[];t=t.1A(3P,"")}F{l(!m[2]||m[1]==".")m[2]="*";H(u i=0;i<\\/2b>");u 2b=15.5z("5V");2b.2A=q(){l(7.2Y!="1I")v;7.1n.3g(7);6.1T()};2b=Q}F l(6.18.3e){6.4r=3R(q(){l(15.2Y=="62"||15.2Y=="1I"){56(6.4r);6.4r=Q;6.1T()}},10)}6.L.1Z(1O,"2T",6.1T)};l(6.18.1y)6(1O).3J(q(){u L=6.L,1i=L.1i;H(u B 1q 1i){u 3H=1i[B],i=3H.D;l(i>0)68 l(B!=\'3J\')L.22(3H[i-1],B);2d(--i)}});6.C.1L({4z:6.C.1C,1C:q(11,G){v 11?7.1W({1z:"1C",27:"1C",1j:"1C"},11,G):7.4z()},5W:6.C.1s,1s:q(11,G){v 11?7.1W({1z:"1s",27:"1s",1j:"1s"},11,G):7.5W()},6h:q(11,G){v 7.1W({1z:"1C"},11,G)},6j:q(11,G){v 7.1W({1z:"1s"},11,G)},6k:q(11,G){v 7.U(q(){u 4B=6(7).4o(":1V")?"1C":"1s";6(7).1W({1z:4B},11,G)})},84:q(11,G){v 7.1W({1j:"1C"},11,G)},6n:q(11,G){v 7.1W({1j:"1s"},11,G)},6q:q(11,2q,G){v 7.1W({1j:2q},11,G)},1W:q(I,11,G){v 7.1w(q(){7.2P=I;H(u p 1q I){u e=1f 6.2O(7,6.11(11,G),p);l(I[p].N==4M)e.2M(e.1m(),I[p]);F e[I[p]](I)}})},1w:q(B,C){l(!C){C=B;B="2O"}v 7.U(q(){l(!7.1w)7.1w={};l(!7.1w[B])7.1w[B]=[];7.1w[B].1l(C);l(7.1w[B].D==1)C.17(7)})}});6.1L({5i:q(e,p){l(e.4K)v;l(p=="1z"&&e.4D!=3f(6.20(e,p)))v;l(p=="27"&&e.4F!=3f(6.20(e,p)))v;u a=e.1a[p];u o=6.20(e,p,1);l(p=="1z"&&e.4D!=o||p=="27"&&e.4F!=o)v;e.1a[p]=e.3t?"":"4I";u n=6.20(e,p,1);l(o!=n&&n!="4I"){e.1a[p]=a;e.4K=V}},11:q(s,o){o=o||{};l(o.N==1v)o={1I:o};u 4N={6x:6z,6A:4H};o.2F=(s&&s.N==4M?s:4N[s])||4S;o.3o=o.1I;o.1I=q(){6.4P(7,"2O");l(o.3o&&o.3o.N==1v)o.3o.17(7)};v o},1w:{},4P:q(E,B){B=B||"2O";l(E.1w&&E.1w[B]){E.1w[B].3O();u f=E.1w[B][0];l(f)f.17(E)}},2O:q(E,2m,I){u z=7;z.o={2F:2m.2F||4S,1I:2m.1I,2p:2m.2p};z.R=E;u y=z.R.1a;z.a=q(){l(2m.2p)2m.2p.17(E,[z.2a]);l(I=="1j")6.1r(y,"1j",z.2a);F l(3f(z.2a))y[I]=3f(z.2a)+"5f";y.1t="2Q"};z.57=q(){v 3Z(6.1g(z.R,I))};z.1m=q(){u r=3Z(6.20(z.R,I));v r&&r>-6R?r:z.57()};z.2M=q(4t,2q){z.42=(1f 54()).55();z.2a=4t;z.a();z.3Y=3R(q(){z.2p(4t,2q)},13)};z.1C=q(p){l(!z.R.1G)z.R.1G={};z.R.1G[I]=7.1m();l(I=="1j")z.2M(z.R.1G[I],1);F z.2M(0,z.R.1G[I]);l(I!="1j")y[I]="6Z"};z.1s=q(){l(!z.R.1G)z.R.1G={};z.R.1G[I]=7.1m();z.o.1s=V;z.2M(z.R.1G[I],0)};l(!z.R.71)z.R.59=6.1g(z.R,"39");y.39="1V";z.2p=q(47,46){u t=(1f 54()).55();l(t>z.o.2F+z.42){56(z.3Y);z.3Y=Q;z.2a=46;z.a();z.R.2P[I]=V;u 1J=V;H(u i 1q z.R.2P)l(z.R.2P[i]!==V)1J=14;l(1J){y.39=z.R.59;l(z.o.1s)y.1t=\'21\';l(z.o.1s){H(u p 1q z.R.2P){l(p=="1j"&&6.18.1y)6.1r(y,p,z.R.1G[p]);F y[p]=z.R.1G[p]+"5f";l(p==\'1z\'||p==\'27\')6.5i(z.R,p)}}}l(1J&&z.o.1I&&z.o.1I.N==1v)z.o.1I.17(z.R)}F{u p=(t-7.42)/z.o.2F;z.2a=((-5t.7m(p*5t.7q)/2)+0.5)*(46-47)+47;z.a()}}}});6.C.1L({7v:q(M,1K,G){7.2T(M,1K,G,1)},2T:q(M,1K,G,1E){l(M.N==1v)v 7.3B("2T",M);G=G||q(){};u B="4d";l(1K){l(1K.N==1v){G=1K;1K=Q}F{1K=6.2C(1K);B="4x"}}u 3q=7;6.3C(B,M,1K,q(3r,12){l(12=="2w"||!1E&&12=="5s"){3q.5y(3r.2Z).U(G,[3r.2Z,12]);6("2b",3q).U(q(){l(7.3m)6.4v(7.3m);F 37.4i(1O,7.2V||7.7A||7.2u||"")})}F G.17(3q,[3r.2Z,12])},1E);v 7},7F:q(){v 6.2C(7)}});l(6.18.1y&&1Y 3b=="P")3b=q(){v 1f 7K(5J.5K.1c("7R 5")>=0?"7U.5P":"7W.5P")};1f q(){u e="4G,5M,5F,5D,5x".3y(",");H(u i=0;i-1)?"&":"?")+6.2C(J);6.3C("4d",M,Q,q(r,12){l(G)G(6.3n(r,B),12)},1E)},5Z:q(M,J,G,B){6.1o(M,J,G,B,1)},4v:q(M,G){6.1o(M,G,"2b")},64:q(M,J,G){l(G)6.1o(M,J,G,"3S");F{6.1o(M,J,"3S")}},6b:q(M,J,G,B){6.3C("4x",M,6.2C(J),q(r,12){l(G)G(6.3n(r,B),12)})},1u:0,6i:q(1u){6.1u=1u},38:{},3C:q(B,M,J,K,1E){l(!M){K=B.1I;u 2w=B.2w;u 2k=B.2k;u 49=B.49;u 1i=1Y B.1i=="85"?B.1i:V;u 1u=1Y B.1u=="6s"?B.1u:6.1u;u 1E=B.1E||14;J=B.J;M=B.M;B=B.B}l(1i&&!6.3I++)6.L.1Q("4G");u 4p=14;u O=1f 3b();O.6y(B||"4d",M,V);l(J)O.30("6D-6E","6F/x-6J-6L-6O");l(1E)O.30("6S-40-6V",6.38[M]||"6W, 6Y 70 72 3V:3V:3V 73");O.30("X-74-75","3b");l(O.78)O.30("7c","7g");u 2A=q(43){l(O&&(O.2Y==4||43=="1u")){4p=V;u 12=6.4y(O)&&43!="1u"?1E&&6.4Q(O,M)?"5s":"2w":"2k";l(12!="2k"){u 3F;3x{3F=O.4b("4T-40")}3h(e){}l(1E&&3F)6.38[M]=3F;l(2w)2w(6.3n(O,49),12);l(1i)6.L.1Q("5x")}F{l(2k)2k(O,12);l(1i)6.L.1Q("5D")}l(1i)6.L.1Q("5F");l(1i&&!--6.3I)6.L.1Q("5M");l(K)K(O,12);O.2A=q(){};O=Q}};O.2A=2A;l(1u>0)7X(q(){l(O){O.82();l(!4p)2A("1u");O=Q}},1u);O.65(J)},3I:0,4y:q(r){3x{v!r.12&&6l.6m=="4l:"||(r.12>=4H&&r.12<6B)||r.12==4W||6.18.3e&&r.12==P}3h(e){}v 14},4Q:q(O,M){3x{u 50=O.4b("4T-40");v O.12==4W||50==6.38[M]||6.18.3e&&O.12==P}3h(e){}v 14},3n:q(r,B){u 4k=r.4b("7G-B");u J=!B&&4k&&4k.1c("O")>=0;J=B=="O"||J?r.8j:r.2Z;l(B=="2b")37.4i(1O,J);l(B=="3S")37("J = "+J);v J},2C:q(a){u s=[];l(a.N==2y||a.2J){H(u i=0;i'; + $(this).prepend(str); + }); + + // attach folds + $(".outline ul li").toggle( + + // hide + function(){ + if ( $(this).children("ul").size() == 0 ) return; + $(this).children("ul").slideUp("slow"); + $(this).find(".linenum").addClass("linenum-folded"); + }, + + // show + function(){ + $(this).children("ul").slideDown("slow"); + $(this).find(".linenum").removeClass("linenum-folded"); + } + ); + +}); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/theme3.js b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/theme3.js new file mode 100644 index 0000000..e3b78cf --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/javascript/theme3.js @@ -0,0 +1,22 @@ +$(document).ready(function(){ + + // append content div + $("body").prepend("
    test
    "); + $("#content").hide(); + + // FIXME - document.width + document.height + $(".outline").click(function(){ + $("#content").html( $(this).html() ); + $("body").background("#7b7c8c"); + $("#content").show(); + }); + + $("#content").click(function(){ + $(this).hide(); + $("body").background("#acadc3"); + }); + + // re-activate links (the event is stomped on by the li event) + $(".outline a").click(function(){ window.location.href = this; return false; }); + +}); diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/sample.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/sample.otl new file mode 100644 index 0000000..aa2dc4e --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/sample.otl @@ -0,0 +1,39 @@ +<:title=Sample OTL list :counts=1 :timer=1 :style=styles/theme1.css :legend=1 :last_mod=1 + +: Theme examples: +: basic advanced advanced2 + +[_] 29% Things to get for party + [_] 25% Food + [_] Chips + [_] Dips + [X] Honey roasted peanuts + [_] Sausage + [_] 33% Party favors + [_] Hats + [_] Whistles + [X] Beer bong + +[_] 19% House projects + [_] 25% Paint + [_] 50% Buy supplies + [_] Paint + [X] Brushes + [X] Trays 2006-09-14 + [_] Overalls + [_] 0% Rooms done + [_] Bathroom + [_] Bedroom + : Red? + [_] 13% Upgrade electrical + [_] 2 circuits to computer room + [_] 40% Get equipment + [X] Romex wire + [_] Entry feed wire + : How much of this do I really need? I should probably go out to the street and measure stuff. + : Make sure the inspector has access to examine stuff on side of house. + [_] Service meter + [X] Grounding rods + [_] Breakers + [_] Learn about electricity + [_] Don't die diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme1.css b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme1.css new file mode 100644 index 0000000..090d945 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme1.css @@ -0,0 +1,88 @@ + +body +{ + width: 600px; + font-size: 0.9em; + font-family: sans; +} + +ul +{ + list-style-type: none; + line-height: 1.5em; + padding-left: 20px; +} + +.date +{ + font-size: 0.6em; +} + +.outline +{ + margin-bottom: 30px; +} + +.percent +{ + color: blue; +} + +.comment, .counts +{ + font-size: 0.7em; + line-height: 1em; + padding-top: 2px; + margin-bottom: 5px; + font-family: sans; +} + +.comment_pre +{ + font-style: normal; + font-family: courier; + white-space: pre; +} + +.counts +{ + margin-left: 10px; +} + +.counts:before { content: "("; } +.counts:after { content: ")"; } + +.todo +{ + padding-left: 4px; +} + +.done +{ + background-color: #f4f4f4; + color: #777; + padding-left: 4px; +} + +.done:before +{ + font-size: 1.5em; + color: green; + content: "\2611 "; +} + +.todo:before +{ + font-size: 1.5em; + color: #777; + content: "\2610 "; +} + +.legend .todo, .legend .done { border: 0 } +.legend +{ + margin-bottom: 30px; + margin-top: 20px; +} + + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme2.css b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme2.css new file mode 100644 index 0000000..869a876 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme2.css @@ -0,0 +1,152 @@ + +body +{ + background-color: #444; + font: 11px/1.8em sans-serif; + margin: 0; + padding-bottom: 50px; + color: #ccc; +} + +a, a:visited +{ + text-decoration: none; + color: #7f9ab5; +} + +.header +{ + background-color: #aaa; + padding: 3px 0 3px 120px; + margin-top: 50px; + color: #3a5f85; + border-top: 5px solid #333; + font-size: 20px; + font-weight: bold; +} + +.last_mod +{ + padding-left: 120px; + background-color: #333; + border-bottom: 1px solid #000; + font-size: 0.85em; + color: #999; +} + +.percent +{ + display: none; + color: #7f9ab5; + font-weight: bold; + position: absolute; + left: 115px; +} + +.linenum +{ + color: #7f9ab5; + position: absolute; + left: 0; + font-size: 9px; + font-weight: normal; + font-style: normal; + width: 60px; + text-align: right; +} + +.linenum-folded +{ + color: #666; +} + +.timer +{ + color: #666; + position: absolute; + top: 5px; + right: 10px; +} + +.outline +{ + width: 400px; + margin: 20px 0 0 150px; + display: none; + cursor: pointer; +} + +.outline ul +{ + margin: 0; + padding: 0 10px 0 5px; + list-style-type: none; +} + +.outline ul li +{ + padding: 0 0 0 10px; + display: block; + color: #fff; + font-size: 14px; + font-weight: bold; +} + +.outline ul li:hover +{ + color: #fff; +} + +.outline ul li ul li +{ + border-left: 1px solid #666; + color: #ccc; + font-size: 11px; + font-weight: normal; +} + +.outline ul li ul li:hover +{ + border-left: 1px solid #aaa; +} + +.done +{ + color: #777 !important; + font-style: italic; +} + +.done:after +{ + font-size: 0.9em; + content: " (done)"; +} + +.comment +{ + padding-right: 2px !important; + font-style: italic; + border-top: 1px solid #666; + border-bottom: 1px solid #666; + border-right: 1px solid #666; +} + +.comment_pre +{ + font-style: normal; + font-family: courier; + white-space: pre; +} + +.comment:hover +{ + border-top: 1px solid #aaa; + border-bottom: 1px solid #aaa; + border-right: 1px solid #aaa; +} + +.selected +{ + background-color: #3d3d3d; +} + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme3.css b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme3.css new file mode 100644 index 0000000..4f8b25c --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otl_handler/styles/theme3.css @@ -0,0 +1,109 @@ + +body +{ + background-color: #acadc3; + font: 12px Verdana, sans-serif; + color: #000; + text-align: center; +} + +a, a:visited +{ + text-decoration: none; + color: blue; +} + +.header +{ + margin-top: 40px; + font-size: 2em; + font-weight: bold; +} + +.header:after { content: " ----|" } +.header:before { content: "|---- " } + +.last_mod { font-size: .85em; } +.percent { font-weight: bold; } + +.sort +{ + margin-bottom: 30px; + font-size: .85em; +} + +.outline +{ + cursor: pointer; + float: left; + padding: 20px; + border: 1px solid #8082a9; + margin-left: 10px; + background-color: #ccc; +} + +.outline:hover +{ + border: 1px solid #000; +} + +.outline ul, #content ul +{ + padding: 0; + margin: 0; + list-style-type: none; +} + +.outline ul li ul li { display: none; } + +#content ul li ul { padding-left: 20px; } + +#content ul li +{ + font-weight: bold; + font-size: 1.5em; + text-align: center; + color: #3a3d85; +} + +#content ul li ul li +{ + font-weight: normal; + text-align: left; + font-size: 10px; + color: #000; +} + +#content .done { color: #777; } +.comment { font-style: italic; } + +#content ul li .percent { color: #ff7e00; } +#content ul li ul li .percent { color: #000; } + +#content .comment +{ + font-style: italic; + border-left: 1px solid #999; + padding-left: 5px; + margin-bottom: 3px; +} + +#content .comment_pre +{ + font-style: normal; + font-family: courier; + white-space: pre; +} + +#content +{ + position: absolute; + left: 15%; + width: 60%; + height: 80%; + cursor: pointer; + background-color: #fff; + border: 2px solid #3a3d85; + padding: 10px; +} + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otlgrep.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/otlgrep.py new file mode 100755 index 0000000..7b2dea3 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otlgrep.py @@ -0,0 +1,212 @@ +#!/usr/bin/python2 +# otlgrep.py +# grep an outline for a regex and return the branch with all the leaves. +# +# Copyright 2005 Noel Henson All rights reserved + +########################################################################### +# Basic function +# +# This program searches an outline file for a branch that contains +# a line matching the regex argument. The parent headings (branches) +# and the children (sub-branches and leaves) of the matching headings +# are returned. +# +# Examples +# +# Using this outline: +# +# Pets +# Indoor +# Cats +# Sophia +# Hillary +# Rats +# Finley +# Oliver +# Dogs +# Kirby +# Outdoor +# Dogs +# Kirby +# Hoover +# Goats +# Primrose +# Joey +# +# a grep for Sophia returns: +# +# Indoor +# Cats +# Sophia +# +# a grep for Dogs returns: +# +# Indoor +# Dogs +# Kirby +# Hoover +# Outdoor +# Dogs +# Kirby +# Hoover +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +########################################################################### +# include whatever mdules we need + +import sys +import re + +########################################################################### +# global variables + +debug = 0 +ignorecase = 0 +pattern = "" +inputfiles = [] + +########################################################################### +# function definitions# usage +# +# print debug statements +# input: string +# output: string printed to standard out + + +def dprint(*vals): + global debug + if debug != 0: + print vals + + +# usage +# print the simplest form of help +# input: none +# output: simple command usage is printed on the console +def showUsage(): + print """ + Usage: + otlgrep.py [options] pattern [file...] + Options + -i Ignore case + --help Show help. + [file...] is zero or more files to search. Wildcards are supported. + if no file is specified, input is expected on stdin. + output is on STDOUT + """ + + +# getArgs +# Check for input arguments and set the necessary switches +# input: none +# output: possible console output for help, switch variables may be set + +def getArgs(): + global debug, pattern, inputfiles, ignorecase + if (len(sys.argv) == 1): + showUsage() + sys.exit()() + else: + for i in range(len(sys.argv)): + if (i != 0): + if (sys.argv[i] == "-d"): + debug = 1 # test for debug flag + elif (sys.argv[i] == "-i"): + ignorecase = 1 # test for debug flag + elif (sys.argv[i] == "-?"): # test for help flag + showUsage() # show the help + sys.exit() # exit + elif (sys.argv[i] == "--help"): + showUsage() + sys.exit() + elif (sys.argv[i][0] == "-"): + print "Error! Unknown option. Aborting" + sys.exit() + else: # get the input file name + if (pattern == ""): + pattern = sys.argv[i] + else: + inputfiles.append(sys.argv[i]) + + +# getLineLevel +# get the level of the current line (count the number of tabs) +# input: linein - a single line that may or may not have tabs at the beginning +# output: returns a number 1 is the lowest +def getLineLevel(linein): + strstart = linein.lstrip() # find the start of text in line + x = linein.find(strstart) # find the text index in the line + n = linein.count("\t", 0, x) # count the tabs + return(n) # return the count + 1 (for level) + + +# processFile +# split an outline file +# input: file - the filehandle of the file we are splitting +# output: output files +def processFile(file): + global debug, pattern, ignorecase + + parents = [] + parentprinted = [] + for i in range(10): + parents.append("") + parentprinted.append(0) + + matchlevel = 0 + line = file.readline() # read the outline title + # and discard it + line = file.readline() # read the first parent heading + while (line != ""): + level = getLineLevel(line) + parents[level] = line + parentprinted[level] = 0 + if (ignorecase == 1): + linesearch = re.search(pattern, line.strip(), re.I) + else: + linesearch = re.search(pattern, line.strip()) + if (linesearch is not None): + matchlevel = level + for i in range(level): # print my ancestors + if (parentprinted[i] == 0): + print parents[i][:-1] + parentprinted[i] = 1 + print parents[level][:-1] # print myself + line = file.readline() + while (line != "") and (getLineLevel(line) > matchlevel): + print line[:-1] + line = file.readline() + else: + line = file.readline() + + +# main +# split an outline +# input: args and input file +# output: output files + +def main(): + global inputfiles, debug + getArgs() + if (len(inputfiles) == 0): + processFile(sys.stdin) + else: + for i in range(len(inputfiles)): + file = open(inputfiles[i], "r") + processFile(file) + file.close() + +main() diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otlhead.sh b/pack/acp/start/vimoutliner/vimoutliner/scripts/otlhead.sh new file mode 100755 index 0000000..ea05fda --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otlhead.sh @@ -0,0 +1,12 @@ +#!/bin/bash +if [ "$#" -lt 1 ] ; then + echo " Usage: otlhead level < file" + echo " Keep the number of levels specified, remove the rest." + echo " Great for generating summaries." + echo " level - the number of levels to include" + echo " file - an otl file" + echo " input - standard in" + echo " output - standard out" + exit 0 +fi +sed "/^\(\t\)\{$1\}.*$/ { D }" diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otlsplit.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/otlsplit.py new file mode 100755 index 0000000..2715e89 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otlsplit.py @@ -0,0 +1,191 @@ +#!/usr/bin/python2 +# otlslit.py +# split an outline into several files. +# +# Copyright 2005 Noel Henson All rights reserved + +########################################################################### +# Basic function +# +# This program accepts text outline files and splits them into +# several smaller files. The output file names are produced from the +# heading names of the parents. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . + +########################################################################### +# include whatever mdules we need + +import sys +import re +########################################################################### +# global variables + +debug = 0 +subdir = "" +level = 1 +title = 0 +inputfile = "" + + +########################################################################### +# function definitions# usage +# +# print debug statements +# input: string +# output: string printed to standard out +def dprint(*vals): + global debug + if debug != 0: + print vals + + +# usage +# print the simplest form of help +# input: none +# output: simple command usage is printed on the console +def showUsage(): + print """ + Usage: + otlsplit.py [options] inputfile + Options + -l level The number of levels to split down to. The default is 1 + -D dir Specifiy a target directory for the output files + -t Include a title line (the parerent heading) in split files + -h Show help. + output is on STDOUT + """ + + +# getArgs +# Check for input arguments and set the necessary switches +# input: none +# output: possible console output for help, switch variables may be set +def getArgs(): + global debug, level, inputfile, title, subdir + if (len(sys.argv) == 1): + showUsage() + sys.exit()() + else: + for i in range(len(sys.argv)): + if (i != 0): + if (sys.argv[i] == "-d"): + debug = 1 # test for debug flag + elif (sys.argv[i] == "-?"): # test for help flag + showUsage() # show the help + sys.exit() # exit + elif (sys.argv[i] == "-l"): # test for the level flag + level = int(sys.argv[i + 1]) # get the level + i = i + 1 # increment the pointer + elif (sys.argv[i] == "-D"): # test for the subdir flag + subdir = sys.argv[i + 1] # get the subdir + i = i + 1 # increment the pointer + elif (sys.argv[i] == "-t"): + title = 1 # test for title flag + elif (sys.argv[i] == "--help"): + showUsage() + sys.exit() + elif (sys.argv[i] == "-h"): + showUsage() + sys.exit() + elif (sys.argv[i][0] == "-"): + print "Error! Unknown option. Aborting" + sys.exit() + else: # get the input file name + inputfile = sys.argv[i] + + +# getLineLevel +# get the level of the current line (count the number of tabs) +# input: linein - a single line that may or may not have tabs at the beginning +# output: returns a number 1 is the lowest +def getLineLevel(linein): + strstart = linein.lstrip() # find the start of text in line + x = linein.find(strstart) # find the text index in the line + n = linein.count("\t", 0, x) # count the tabs + return(n + 1) # return the count + 1 (for level) + + +# convertSensitiveChars +# get the level of the current line (count the number of tabs) +# input: line - a single line that may or may not have tabs at the beginning +# output: returns a string +def convertSensitiveChars(line): + line = re.sub('\W', '_', line.strip()) + return(line) + + +# makeFileName +# make a file name from the string array provided +# input: line - a single line that may or may not have tabs at the beginning +# output: returns a string +def makeFileName(nameParts): + global debug, level, subdir + + filename = "" + for i in range(level): + filename = filename + convertSensitiveChars(nameParts[i]).strip() + "-" + filename = filename[:-1] + ".otl" + if subdir != "": + filename = subdir + "/" + filename + return(filename.lower()) + + +# processFile +# split an outline file +# input: file - the filehandle of the file we are splitting +# output: output files +def processFile(ifile): + global debug, level, title + + nameparts = [] + for i in range(10): + nameparts.append("") + + outOpen = 0 + + line = ifile.readline() # read the outline title + # and discard it + line = ifile.readline() # read the first parent heading + dprint(level) + while (line != ""): + linelevel = getLineLevel(line) + if (linelevel < level): + if outOpen == 1: + ifile.close() + outOpen = 0 + nameparts[linelevel] = line + dprint(level, linelevel, line) + else: + if outOpen == 0: + ofile = open(makeFileName(nameparts), "w") + outOpen = 1 + if title == 1: + dprint("title:", title) + ofile.write(nameparts[level - 1]) + ofile.write(line[level:]) + line = file.readline() + + +# main +# split an outline +# input: args and input file +# output: output files +def main(): + global inputfile, debug + getArgs() + file = open(inputfile, "r") + processFile(file) + file.close() + +main() diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/otltail.sh b/pack/acp/start/vimoutliner/vimoutliner/scripts/otltail.sh new file mode 100755 index 0000000..82df8a0 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/otltail.sh @@ -0,0 +1,15 @@ +#!/bin/bash +if [ "$#" -lt 1 ] ; then + echo " Usage: otltail level < file" + echo " Remove the specified number of parent headings." + echo " This is a way to promote children. It is" + echo " useful for converting a single outline into a" + echo " number of pages for a web site or chapters for" + echo " a book." + echo " level - the number of levels to include" + echo " file - an otl file" + echo " input - standard in" + echo " output - standard out" + exit 0 +fi +sed "/^\(\t\)\{$1\}.*$/! { D }" | sed "s/^\(\t\)\{$1\}//" diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/2005.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/2005.otl new file mode 100644 index 0000000..5d93abe --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/2005.otl @@ -0,0 +1,1472 @@ +January 2005 + 2005_01_01 Sat + To do + Diary + Timesheet + 2005_01_02 Sun + To do + Diary + Timesheet + 2005_01_03 Mon + To do + Diary + Timesheet + 2005_01_04 Tue + To do + Diary + Timesheet + 2005_01_05 Wed + To do + Diary + Timesheet + 2005_01_06 Thu + To do + Diary + Timesheet + 2005_01_07 Fri + To do + Diary + Timesheet + 2005_01_08 Sat + To do + Diary + Timesheet + 2005_01_09 Sun + To do + Diary + Timesheet + 2005_01_10 Mon + To do + Diary + Timesheet + 2005_01_11 Tue + To do + Diary + Timesheet + 2005_01_12 Wed + To do + Diary + Timesheet + 2005_01_13 Thu + To do + Diary + Timesheet + 2005_01_14 Fri + To do + Diary + Timesheet + 2005_01_15 Sat + To do + Diary + Timesheet + 2005_01_16 Sun + To do + Diary + Timesheet + 2005_01_17 Mon + To do + Diary + Timesheet + 2005_01_18 Tue + To do + Diary + Timesheet + 2005_01_19 Wed + To do + Diary + Timesheet + 2005_01_20 Thu + To do + Diary + Timesheet + 2005_01_21 Fri + To do + Diary + Timesheet + 2005_01_22 Sat + To do + Diary + Timesheet + 2005_01_23 Sun + To do + Diary + Timesheet + 2005_01_24 Mon + To do + Diary + Timesheet + 2005_01_25 Tue + To do + Diary + Timesheet + 2005_01_26 Wed + To do + Diary + Timesheet + 2005_01_27 Thu + To do + Diary + Timesheet + 2005_01_28 Fri + To do + Diary + Timesheet + 2005_01_29 Sat + To do + Diary + Timesheet + 2005_01_30 Sun + To do + Diary + Timesheet + 2005_01_31 Mon + To do + Diary + Timesheet +February 2005 + 2005_02_01 Tue + To do + Diary + Timesheet + 2005_02_02 Wed + To do + Diary + Timesheet + 2005_02_03 Thu + To do + Diary + Timesheet + 2005_02_04 Fri + To do + Diary + Timesheet + 2005_02_05 Sat + To do + Diary + Timesheet + 2005_02_06 Sun + To do + Diary + Timesheet + 2005_02_07 Mon + To do + Diary + Timesheet + 2005_02_08 Tue + To do + Diary + Timesheet + 2005_02_09 Wed + To do + Diary + Timesheet + 2005_02_10 Thu + To do + Diary + Timesheet + 2005_02_11 Fri + To do + Diary + Timesheet + 2005_02_12 Sat + To do + Diary + Timesheet + 2005_02_13 Sun + To do + Diary + Timesheet + 2005_02_14 Mon + To do + Diary + Timesheet + 2005_02_15 Tue + To do + Diary + Timesheet + 2005_02_16 Wed + To do + Diary + Timesheet + 2005_02_17 Thu + To do + Diary + Timesheet + 2005_02_18 Fri + To do + Diary + Timesheet + 2005_02_19 Sat + To do + Diary + Timesheet + 2005_02_20 Sun + To do + Diary + Timesheet + 2005_02_21 Mon + To do + Diary + Timesheet + 2005_02_22 Tue + To do + Diary + Timesheet + 2005_02_23 Wed + To do + Diary + Timesheet + 2005_02_24 Thu + To do + Diary + Timesheet + 2005_02_25 Fri + To do + Diary + Timesheet + 2005_02_26 Sat + To do + Diary + Timesheet + 2005_02_27 Sun + To do + Diary + Timesheet + 2005_02_28 Mon + To do + Diary + Timesheet +March 2005 + 2005_03_01 Tue + To do + Diary + Timesheet + 2005_03_02 Wed + To do + Diary + Timesheet + 2005_03_03 Thu + To do + Diary + Timesheet + 2005_03_04 Fri + To do + Diary + Timesheet + 2005_03_05 Sat + To do + Diary + Timesheet + 2005_03_06 Sun + To do + Diary + Timesheet + 2005_03_07 Mon + To do + Diary + Timesheet + 2005_03_08 Tue + To do + Diary + Timesheet + 2005_03_09 Wed + To do + Diary + Timesheet + 2005_03_10 Thu + To do + Diary + Timesheet + 2005_03_11 Fri + To do + Diary + Timesheet + 2005_03_12 Sat + To do + Diary + Timesheet + 2005_03_13 Sun + To do + Diary + Timesheet + 2005_03_14 Mon + To do + Diary + Timesheet + 2005_03_15 Tue + To do + Diary + Timesheet + 2005_03_16 Wed + To do + Diary + Timesheet + 2005_03_17 Thu + To do + Diary + Timesheet + 2005_03_18 Fri + To do + Diary + Timesheet + 2005_03_19 Sat + To do + Diary + Timesheet + 2005_03_20 Sun + To do + Diary + Timesheet + 2005_03_21 Mon + To do + Diary + Timesheet + 2005_03_22 Tue + To do + Diary + Timesheet + 2005_03_23 Wed + To do + Diary + Timesheet + 2005_03_24 Thu + To do + Diary + Timesheet + 2005_03_25 Fri + To do + Diary + Timesheet + 2005_03_26 Sat + To do + Diary + Timesheet + 2005_03_27 Sun + To do + Diary + Timesheet + 2005_03_28 Mon + To do + Diary + Timesheet + 2005_03_29 Tue + To do + Diary + Timesheet + 2005_03_30 Wed + To do + Diary + Timesheet + 2005_03_31 Thu + To do + Diary + Timesheet +April 2005 + 2005_04_01 Fri + To do + Diary + Timesheet + 2005_04_02 Sat + To do + Diary + Timesheet + 2005_04_03 Sun + To do + Diary + Timesheet + 2005_04_04 Mon + To do + Diary + Timesheet + 2005_04_05 Tue + To do + Diary + Timesheet + 2005_04_06 Wed + To do + Diary + Timesheet + 2005_04_07 Thu + To do + Diary + Timesheet + 2005_04_08 Fri + To do + Diary + Timesheet + 2005_04_09 Sat + To do + Diary + Timesheet + 2005_04_10 Sun + To do + Diary + Timesheet + 2005_04_11 Mon + To do + Diary + Timesheet + 2005_04_12 Tue + To do + Diary + Timesheet + 2005_04_13 Wed + To do + Diary + Timesheet + 2005_04_14 Thu + To do + Diary + Timesheet + 2005_04_15 Fri + To do + Diary + Timesheet + 2005_04_16 Sat + To do + Diary + Timesheet + 2005_04_17 Sun + To do + Diary + Timesheet + 2005_04_18 Mon + To do + Diary + Timesheet + 2005_04_19 Tue + To do + Diary + Timesheet + 2005_04_20 Wed + To do + Diary + Timesheet + 2005_04_21 Thu + To do + Diary + Timesheet + 2005_04_22 Fri + To do + Diary + Timesheet + 2005_04_23 Sat + To do + Diary + Timesheet + 2005_04_24 Sun + To do + Diary + Timesheet + 2005_04_25 Mon + To do + Diary + Timesheet + 2005_04_26 Tue + To do + Diary + Timesheet + 2005_04_27 Wed + To do + Diary + Timesheet + 2005_04_28 Thu + To do + Diary + Timesheet + 2005_04_29 Fri + To do + Diary + Timesheet + 2005_04_30 Sat + To do + Diary + Timesheet +May 2005 + 2005_05_01 Sun + To do + Diary + Timesheet + 2005_05_02 Mon + To do + Diary + Timesheet + 2005_05_03 Tue + To do + Diary + Timesheet + 2005_05_04 Wed + To do + Diary + Timesheet + 2005_05_05 Thu + To do + Diary + Timesheet + 2005_05_06 Fri + To do + Diary + Timesheet + 2005_05_07 Sat + To do + Diary + Timesheet + 2005_05_08 Sun + To do + Diary + Timesheet + 2005_05_09 Mon + To do + Diary + Timesheet + 2005_05_10 Tue + To do + Diary + Timesheet + 2005_05_11 Wed + To do + Diary + Timesheet + 2005_05_12 Thu + To do + Diary + Timesheet + 2005_05_13 Fri + To do + Diary + Timesheet + 2005_05_14 Sat + To do + Diary + Timesheet + 2005_05_15 Sun + To do + Diary + Timesheet + 2005_05_16 Mon + To do + Diary + Timesheet + 2005_05_17 Tue + To do + Diary + Timesheet + 2005_05_18 Wed + To do + Diary + Timesheet + 2005_05_19 Thu + To do + Diary + Timesheet + 2005_05_20 Fri + To do + Diary + Timesheet + 2005_05_21 Sat + To do + Diary + Timesheet + 2005_05_22 Sun + To do + Diary + Timesheet + 2005_05_23 Mon + To do + Diary + Timesheet + 2005_05_24 Tue + To do + Diary + Timesheet + 2005_05_25 Wed + To do + Diary + Timesheet + 2005_05_26 Thu + To do + Diary + Timesheet + 2005_05_27 Fri + To do + Diary + Timesheet + 2005_05_28 Sat + To do + Diary + Timesheet + 2005_05_29 Sun + To do + Diary + Timesheet + 2005_05_30 Mon + To do + Diary + Timesheet + 2005_05_31 Tue + To do + Diary + Timesheet +June 2005 + 2005_06_01 Wed + To do + Diary + Timesheet + 2005_06_02 Thu + To do + Diary + Timesheet + 2005_06_03 Fri + To do + Diary + Timesheet + 2005_06_04 Sat + To do + Diary + Timesheet + 2005_06_05 Sun + To do + Diary + Timesheet + 2005_06_06 Mon + To do + Diary + Timesheet + 2005_06_07 Tue + To do + Diary + Timesheet + 2005_06_08 Wed + To do + Diary + Timesheet + 2005_06_09 Thu + To do + Diary + Timesheet + 2005_06_10 Fri + To do + Diary + Timesheet + 2005_06_11 Sat + To do + Diary + Timesheet + 2005_06_12 Sun + To do + Diary + Timesheet + 2005_06_13 Mon + To do + Diary + Timesheet + 2005_06_14 Tue + To do + Diary + Timesheet + 2005_06_15 Wed + To do + Diary + Timesheet + 2005_06_16 Thu + To do + Diary + Timesheet + 2005_06_17 Fri + To do + Diary + Timesheet + 2005_06_18 Sat + To do + Diary + Timesheet + 2005_06_19 Sun + To do + Diary + Timesheet + 2005_06_20 Mon + To do + Diary + Timesheet + 2005_06_21 Tue + To do + Diary + Timesheet + 2005_06_22 Wed + To do + Diary + Timesheet + 2005_06_23 Thu + To do + Diary + Timesheet + 2005_06_24 Fri + To do + Diary + Timesheet + 2005_06_25 Sat + To do + Diary + Timesheet + 2005_06_26 Sun + To do + Diary + Timesheet + 2005_06_27 Mon + To do + Diary + Timesheet + 2005_06_28 Tue + To do + Diary + Timesheet + 2005_06_29 Wed + To do + Diary + Timesheet + 2005_06_30 Thu + To do + Diary + Timesheet +July 2005 + 2005_07_01 Fri + To do + Diary + Timesheet + 2005_07_02 Sat + To do + Diary + Timesheet + 2005_07_03 Sun + To do + Diary + Timesheet + 2005_07_04 Mon + To do + Diary + Timesheet + 2005_07_05 Tue + To do + Diary + Timesheet + 2005_07_06 Wed + To do + Diary + Timesheet + 2005_07_07 Thu + To do + Diary + Timesheet + 2005_07_08 Fri + To do + Diary + Timesheet + 2005_07_09 Sat + To do + Diary + Timesheet + 2005_07_10 Sun + To do + Diary + Timesheet + 2005_07_11 Mon + To do + Diary + Timesheet + 2005_07_12 Tue + To do + Diary + Timesheet + 2005_07_13 Wed + To do + Diary + Timesheet + 2005_07_14 Thu + To do + Diary + Timesheet + 2005_07_15 Fri + To do + Diary + Timesheet + 2005_07_16 Sat + To do + Diary + Timesheet + 2005_07_17 Sun + To do + Diary + Timesheet + 2005_07_18 Mon + To do + Diary + Timesheet + 2005_07_19 Tue + To do + Diary + Timesheet + 2005_07_20 Wed + To do + Diary + Timesheet + 2005_07_21 Thu + To do + Diary + Timesheet + 2005_07_22 Fri + To do + Diary + Timesheet + 2005_07_23 Sat + To do + Diary + Timesheet + 2005_07_24 Sun + To do + Diary + Timesheet + 2005_07_25 Mon + To do + Diary + Timesheet + 2005_07_26 Tue + To do + Diary + Timesheet + 2005_07_27 Wed + To do + Diary + Timesheet + 2005_07_28 Thu + To do + Diary + Timesheet + 2005_07_29 Fri + To do + Diary + Timesheet + 2005_07_30 Sat + To do + Diary + Timesheet + 2005_07_31 Sun + To do + Diary + Timesheet +August 2005 + 2005_08_01 Mon + To do + Diary + Timesheet + 2005_08_02 Tue + To do + Diary + Timesheet + 2005_08_03 Wed + To do + Diary + Timesheet + 2005_08_04 Thu + To do + Diary + Timesheet + 2005_08_05 Fri + To do + Diary + Timesheet + 2005_08_06 Sat + To do + Diary + Timesheet + 2005_08_07 Sun + To do + Diary + Timesheet + 2005_08_08 Mon + To do + Diary + Timesheet + 2005_08_09 Tue + To do + Diary + Timesheet + 2005_08_10 Wed + To do + Diary + Timesheet + 2005_08_11 Thu + To do + Diary + Timesheet + 2005_08_12 Fri + To do + Diary + Timesheet + 2005_08_13 Sat + To do + Diary + Timesheet + 2005_08_14 Sun + To do + Diary + Timesheet + 2005_08_15 Mon + To do + Diary + Timesheet + 2005_08_16 Tue + To do + Diary + Timesheet + 2005_08_17 Wed + To do + Diary + Timesheet + 2005_08_18 Thu + To do + Diary + Timesheet + 2005_08_19 Fri + To do + Diary + Timesheet + 2005_08_20 Sat + To do + Diary + Timesheet + 2005_08_21 Sun + To do + Diary + Timesheet + 2005_08_22 Mon + To do + Diary + Timesheet + 2005_08_23 Tue + To do + Diary + Timesheet + 2005_08_24 Wed + To do + Diary + Timesheet + 2005_08_25 Thu + To do + Diary + Timesheet + 2005_08_26 Fri + To do + Diary + Timesheet + 2005_08_27 Sat + To do + Diary + Timesheet + 2005_08_28 Sun + To do + Diary + Timesheet + 2005_08_29 Mon + To do + Diary + Timesheet + 2005_08_30 Tue + To do + Diary + Timesheet + 2005_08_31 Wed + To do + Diary + Timesheet +September 2005 + 2005_09_01 Thu + To do + Diary + Timesheet + 2005_09_02 Fri + To do + Diary + Timesheet + 2005_09_03 Sat + To do + Diary + Timesheet + 2005_09_04 Sun + To do + Diary + Timesheet + 2005_09_05 Mon + To do + Diary + Timesheet + 2005_09_06 Tue + To do + Diary + Timesheet + 2005_09_07 Wed + To do + Diary + Timesheet + 2005_09_08 Thu + To do + Diary + Timesheet + 2005_09_09 Fri + To do + Diary + Timesheet + 2005_09_10 Sat + To do + Diary + Timesheet + 2005_09_11 Sun + To do + Diary + Timesheet + 2005_09_12 Mon + To do + Diary + Timesheet + 2005_09_13 Tue + To do + Diary + Timesheet + 2005_09_14 Wed + To do + Diary + Timesheet + 2005_09_15 Thu + To do + Diary + Timesheet + 2005_09_16 Fri + To do + Diary + Timesheet + 2005_09_17 Sat + To do + Diary + Timesheet + 2005_09_18 Sun + To do + Diary + Timesheet + 2005_09_19 Mon + To do + Diary + Timesheet + 2005_09_20 Tue + To do + Diary + Timesheet + 2005_09_21 Wed + To do + Diary + Timesheet + 2005_09_22 Thu + To do + Diary + Timesheet + 2005_09_23 Fri + To do + Diary + Timesheet + 2005_09_24 Sat + To do + Diary + Timesheet + 2005_09_25 Sun + To do + Diary + Timesheet + 2005_09_26 Mon + To do + Diary + Timesheet + 2005_09_27 Tue + To do + Diary + Timesheet + 2005_09_28 Wed + To do + Diary + Timesheet + 2005_09_29 Thu + To do + Diary + Timesheet + 2005_09_30 Fri + To do + Diary + Timesheet +October 2005 + 2005_10_01 Sat + To do + Diary + Timesheet + 2005_10_02 Sun + To do + Diary + Timesheet + 2005_10_03 Mon + To do + Diary + Timesheet + 2005_10_04 Tue + To do + Diary + Timesheet + 2005_10_05 Wed + To do + Diary + Timesheet + 2005_10_06 Thu + To do + Diary + Timesheet + 2005_10_07 Fri + To do + Diary + Timesheet + 2005_10_08 Sat + To do + Diary + Timesheet + 2005_10_09 Sun + To do + Diary + Timesheet + 2005_10_10 Mon + To do + Diary + Timesheet + 2005_10_11 Tue + To do + Diary + Timesheet + 2005_10_12 Wed + To do + Diary + Timesheet + 2005_10_13 Thu + To do + Diary + Timesheet + 2005_10_14 Fri + To do + Diary + Timesheet + 2005_10_15 Sat + To do + Diary + Timesheet + 2005_10_16 Sun + To do + Diary + Timesheet + 2005_10_17 Mon + To do + Diary + Timesheet + 2005_10_18 Tue + To do + Diary + Timesheet + 2005_10_19 Wed + To do + Diary + Timesheet + 2005_10_20 Thu + To do + Diary + Timesheet + 2005_10_21 Fri + To do + Diary + Timesheet + 2005_10_22 Sat + To do + Diary + Timesheet + 2005_10_23 Sun + To do + Diary + Timesheet + 2005_10_24 Mon + To do + Diary + Timesheet + 2005_10_25 Tue + To do + Diary + Timesheet + 2005_10_26 Wed + To do + Diary + Timesheet + 2005_10_27 Thu + To do + Diary + Timesheet + 2005_10_28 Fri + To do + Diary + Timesheet + 2005_10_29 Sat + To do + Diary + Timesheet + 2005_10_30 Sun + To do + Diary + Timesheet + 2005_10_31 Mon + To do + Diary + Timesheet +November 2005 + 2005_11_01 Tue + To do + Diary + Timesheet + 2005_11_02 Wed + To do + Diary + Timesheet + 2005_11_03 Thu + To do + Diary + Timesheet + 2005_11_04 Fri + To do + Diary + Timesheet + 2005_11_05 Sat + To do + Diary + Timesheet + 2005_11_06 Sun + To do + Diary + Timesheet + 2005_11_07 Mon + To do + Diary + Timesheet + 2005_11_08 Tue + To do + Diary + Timesheet + 2005_11_09 Wed + To do + Diary + Timesheet + 2005_11_10 Thu + To do + Diary + Timesheet + 2005_11_11 Fri + To do + Diary + Timesheet + 2005_11_12 Sat + To do + Diary + Timesheet + 2005_11_13 Sun + To do + Diary + Timesheet + 2005_11_14 Mon + To do + Diary + Timesheet + 2005_11_15 Tue + To do + Diary + Timesheet + 2005_11_16 Wed + To do + Diary + Timesheet + 2005_11_17 Thu + To do + Diary + Timesheet + 2005_11_18 Fri + To do + Diary + Timesheet + 2005_11_19 Sat + To do + Diary + Timesheet + 2005_11_20 Sun + To do + Diary + Timesheet + 2005_11_21 Mon + To do + Diary + Timesheet + 2005_11_22 Tue + To do + Diary + Timesheet + 2005_11_23 Wed + To do + Diary + Timesheet + 2005_11_24 Thu + To do + Diary + Timesheet + 2005_11_25 Fri + To do + Diary + Timesheet + 2005_11_26 Sat + To do + Diary + Timesheet + 2005_11_27 Sun + To do + Diary + Timesheet + 2005_11_28 Mon + To do + Diary + Timesheet + 2005_11_29 Tue + To do + Diary + Timesheet + 2005_11_30 Wed + To do + Diary + Timesheet +December 2005 + 2005_12_01 Thu + To do + Diary + Timesheet + 2005_12_02 Fri + To do + Diary + Timesheet + 2005_12_03 Sat + To do + Diary + Timesheet + 2005_12_04 Sun + To do + Diary + Timesheet + 2005_12_05 Mon + To do + Diary + Timesheet + 2005_12_06 Tue + To do + Diary + Timesheet + 2005_12_07 Wed + To do + Diary + Timesheet + 2005_12_08 Thu + To do + Diary + Timesheet + 2005_12_09 Fri + To do + Diary + Timesheet + 2005_12_10 Sat + To do + Diary + Timesheet + 2005_12_11 Sun + To do + Diary + Timesheet + 2005_12_12 Mon + To do + Diary + Timesheet + 2005_12_13 Tue + To do + Diary + Timesheet + 2005_12_14 Wed + To do + Diary + Timesheet + 2005_12_15 Thu + To do + Diary + Timesheet + 2005_12_16 Fri + To do + Diary + Timesheet + 2005_12_17 Sat + To do + Diary + Timesheet + 2005_12_18 Sun + To do + Diary + Timesheet + 2005_12_19 Mon + To do + Diary + Timesheet + 2005_12_20 Tue + To do + Diary + Timesheet + 2005_12_21 Wed + To do + Diary + Timesheet + 2005_12_22 Thu + To do + Diary + Timesheet + 2005_12_23 Fri + To do + Diary + Timesheet + 2005_12_24 Sat + To do + Diary + Timesheet + 2005_12_25 Sun + To do + Diary + Timesheet + 2005_12_26 Mon + To do + Diary + Timesheet + 2005_12_27 Tue + To do + Diary + Timesheet + 2005_12_28 Wed + To do + Diary + Timesheet + 2005_12_29 Thu + To do + Diary + Timesheet + 2005_12_30 Fri + To do + Diary + Timesheet + 2005_12_31 Sat + To do + Diary + Timesheet diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vimrc b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vimrc new file mode 100644 index 0000000..7537878 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vimrc @@ -0,0 +1,31 @@ +" add the calendar tag file to the tag search stack +set tags^=~/Outlines/outline_calendar/vo_calendar_tags.tag + +" open the calendar at date +" a:1 is executed before the jump +function ToDate(date, ...) + let l:precmd = a:0>0 ? a:1 : "" + exec l:precmd + exec "tag " . a:date . "|normal zO" +endfunction + +" open the calendar at a requested date +" default is today +" a:1 is executed before the jump +function ToSomeDay(...) + let l:precmd = a:0>0 ? a:1 : "" + let l:today = strftime("%Y-%m-%d") + let l:date = input('Date To Goto (yyyy-mm-dd): ', today) + call ToDate(l:date, l:precmd) +endfunction + +" small case jumps use same window +nmap td :call ToDate(strftime("%Y-%m-%d")) +nmap ts :call ToSomeDay() +nmap tc :call ToDate(expand("")) + +" upper case jumps open new window +nmap tD :call ToDate(strftime("%Y-%m-%d"),"new") +nmap tS :call ToSomeDay("new") +nmap tC :call ToDate(expand(""),"new") + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ctags.conf b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ctags.conf new file mode 100644 index 0000000..579da09 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ctags.conf @@ -0,0 +1,9 @@ +--langdef=outline +--langmap=outline:.otl +--regex-outline=/_tag_ set ([^ ]+)/_tag_\1/ +--regex-outline=/^\t+([1-9][0-9]{3})_([01][0-9])_([0-3][0-9])/\1-\2-\3/ + +--languages=-all,+outline +--recurse + +--totals=yes diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_generator.rb b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_generator.rb new file mode 100755 index 0000000..adbbc6f --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_generator.rb @@ -0,0 +1,110 @@ +#!/usr/bin/ruby + +# usage: +# calendar_generator.rb + +# indent for months, days are indented one more level +# both 0 and 1 make sense +MONTHINDENT = 0 + + +# insert _tag_ todo and _tag_ done items under each day +# DIARY = ["Zu erledigen", "Tagebuch", "Abrechnen"] +# DIARY = [] # for empty days. +DIARY = ["To do", "Diary", "Timesheet"] # deluxe edition + + +# adapt to your preference +# Sunday should be first, Saturday last entry +# DAYNAMES = %w(So Mo Di Mi Do Fr Sa) +DAYNAMES = %w(Sun Mon Tue Wed Thu Fri Sat) + + +# January should be first, December last entry +# MONTHNAMES = %w(Januar Februar Mrz April Mai Juni Juli August September Oktober November Dezember) +MONTHNAMES = %w(January February March April May June July August September October November December) + +# you should not need to change anything below here +# but you are welcome to write equivalent functionality +# in your language of choice. +# ------------------------------------------------------------ +require "date" + +TAGFORMAT = "%.4d_%.2d_%.2d" + + +def indent(sublevel) + "\t"*(MONTHINDENT+sublevel) +end + +def month(date) + MONTHNAMES[date.month - 1] + + (MONTHINDENT == 0 ? " " + date.year.to_s : "") +end + +class Shelf + def initialize(path) + begin + @shelf = File.readlines(path) + rescue + @shelf = Array.new + end + @path = path + end + def parse + unless @books + @books = Hash.new + (0...@shelf.size).step(2) do |i| + @books[@shelf[i].strip] = @shelf[i+1].strip + end + end + end + def save() + File.open(@path, "w") do |out| + @books.sort.each do |key,value| + out.puts(key) + out.puts("\t" + value) + end if @books + end + end + def update(year) + re = /^_tag_calendar_#{year}/ + unless @shelf.any? { |str| re.match(str) } + parse + @books["_tag_calendar_#{year}"] = "#{year}.otl" + save + end + end +end + +def update_shelf(year) + shelf = Shelf.new(CALENDAR + "/vo_calendar_shelf.otl") + shelf.update(year) +end + +CALENDAR = ARGV.shift + +ARGV.each do |arg| + + File.open(CALENDAR + "/" + arg + ".otl", "w") do |out| + + update_shelf(arg) + year = arg.to_i + d = Date.new(year, 1, 1) + out.puts year if MONTHINDENT == 1 + + while d.year == year + out.puts indent(0) + month(d) + month = d.month + while d.month == month + out.puts indent(1) + (TAGFORMAT % [d.year, d.month, d.day]) + + " " + DAYNAMES[d.wday] + DIARY.each do |item| + out.puts indent(2) + item + end + d += 1 + end + end + + end +end diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_readme.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_readme.otl new file mode 100644 index 0000000..5761781 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_readme.otl @@ -0,0 +1,195 @@ +Outline Calendar 1.3 + What's new + in 1.3 + vimrc-script by Lee Bigelow for easy calendar access + small modifications to this outline + update from 1.2.2 + edit tagfile path in outline_calendar/vimrc + add 'source .../outline_calendar/vimrc' to your ~/.vimrc + in 1.2.2 + changed personal _tag_ set definition + : it may appear anywhere, but takes only next space-delimited + : word into account. The advantage is that I can set a tag + : behind a calendar date and jump to the current week via + : _tag_kalender + in 1.2.1 + removed spurious underscores in td function + in 1.2 + use ~/.vimoutlinerrc to avoid tagfile collisions + ,,d-dates usable as links into calendar + calendar dates (almost) without syntactic noise + update to documentation + in 1.1 + we are almost votl_maketags.pl-compatible again + you can use vo_calendar_shelf.otl to attach your calendar shelf to your outline tree + files follow vimoutliner naming convention + all installation files are kept within one directory + minor refinements to console user interface + defaults and samples are in English now + Prerequisites + ruby + used for generating the skeleton calendar and the shelf + could be replaced by perl, awk, python, ... + maybe even by a shell script or a small forth program ;-) + bash + use of special variable expansion in shell-frontend + ctags + create the tags-file for interoutline links and calendar access + regex support necessary + $ ctags --version + : Exuberant Ctags 5.5.1, Copyright (C) 1996-2003 Darren Hiebert + : Compiled: Aug 15 2003, 21:06:30 + : Addresses: , http://ctags.sourceforge.net + : Optional compiled features: +wildcards, +regex + vimoutliner + you should already have it + Known incompatibilities + none + Installation and Configuration + Installation + I recommend keeping all Outlines in one directory + it's easier on ctags + move the distribution folder there + : $ mv outline_calendar ~/Outlines + add another tag file to vim's lookup table + the following line should go into $HOME/.vimrc + : source ~/Outlines/outline_calendar/vimrc + configure the various scripts (see below) + source vo_calendar_ui.sh into your shell + $HOME/.bashrc is probably a good place for this + something like the following should do it + $ . $HOME/Outlines/outline_calendar/vo_calendar_ui.sh + you're ready to run + try + $ calgen 2005 2006 2007 + : you get three yearly calendars plus a shelf to + : access them through _tag_xxx linking + $ tagvout + : this should create a tag file inside the outline + : calendar directory + $ td + : now vimoutliner should be positioned on today + $ vim + in normal mode type \tS + enter a date after the prompt and hit return + the calendar should open in a new window + Configure the calendar layout in vo_calendar_generator.rb + Month layout + with MONTHINDENT=1 + 2006 + January + _2006-01-01_ Sun + _2006-01-02_ Mon + or with MONTHINDENT=0 + January 2006 + _2006-01-01_ Sun + _2006-01-02_ Mon + Optional diary headings for each day + with DIARY=[] + _2006-01-01_ Sun + _2006-01-02_ Mon + with DIARY=["Todo", "Billing", "Personal notes"] + _2006-01-01_ Sun + Todo + Billing + Personal notes + _2006-01-02_ Mon + Todo + Billing + Personal notes + change the language of the calendar + DAYNAMES + names of weekdays starting with Sunday + MONTHNAMES + names of months + calendar skeletons + need not be generated with the ruby script + but we do have an "API" to keep things compatible + : I suggest an approach that can be executed in + : the same way as my ruby script. If you did it + : with perl, you could call the script + : vo_calendar_generator.pl. + : Its first command line parameter should be the + : directory, where the calendar files are stored, + : the remaining parameters denote the years, for which + : calendar skeletons should be generated. + calendar shelf + do not edit manually, a really stupid parser (tm) is reading this + : it contains the _tag_ format links into the various + : yearly calendars. It is "parsed" (if you can call it + : that) to insert a newly created calendar in the correct + : position. + Configure the directory layout in vo_calendar_ui.sh + See the comments there for further explanations + Ideally you only have to set the variable OUTLINES, but YMMV + Configure tag harvesting in vo_calendar_ctags.conf + it should not need any changes + if it does, "man 1 ctags" is your friend + what it does, line by line + define a new language called outline + outline handling rules are applied only to .otl files + recognise headings starting with "_tag_ set " + everything after "_tag_ set " is considered as tag content + : this provides an alternative way of defining tags + : for both interoutline and intraoutline jumps. + : It can safely be removed without harming the + : outline calendar. + : If you keep it, your non-calendar tags will be + : stored in the calendar tagfile, too, but this should + : not be a problem. + recognise headings starting with a yyyy_mm_dd date + Underscore as date separator + are distinct from ,,d dates + date stamps will not be jumped to + date stamps will only be jumped from + they are mangled to hyphens as tag marker + plain ,,d dates can be used to enter the calendar from anywhere + all dates typed by you are in ISO-format yyyy-mm-dd + only tag outline files + handle files in subdirectories, too + show some impressive statistics + Usage + administrative + once: install and configure (see above) + rarely: generate a new calendar + $ calgen 2005 2006 2007 + this will go a long way + often: refresh the tag file + $ tagvout + you might even want to put it in your crontab + don't rely on shell functions there, use plain commands + modulo local changes the crontab entry would look like this: + : */10 * * * * /usr/bin/ctags -f $HOME/.vimoutliner/vo_tags.tag --options=$HOME/Outlines/outline_calendar/vo_calendar_ctags.conf $HOME/Outlines &> /dev/null + refresh tag file every 10 minutes + remove the configuration line --totals, you won't need it there + open calendar from running shell + edit today's calendar entries + $ td + : vimoutliner should open on today + : if you're running X, you'll get a gvim, otherwise a vim + : you'll be on today's entry + move around, add some items to the outline + move cursor on a ISO-format date yyyy-mm-dd and it + edit any available day + $ td 2005-05-04 + : release day + open calendar from running vim session + mappings for normal mode + \td and \tD + jump to today + \tc and \tC + jump to the date at the cursor position + \ts and \tS + ask for date to jump to + Notes + the mappings are defined as t... + the uppercase variant opens a new window within the current session + Author(s) + (c) Stefan Schmiedl 2005-05-04 + Contributors: + Lee Bigelow brought the \t? functions into existence + License + thou shalt neither sue nor blame me + it's worth what you paid for it + thou can do whatever else thou want to do with it + just remember to have fun on the way diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_shelf.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_shelf.otl new file mode 100644 index 0000000..d8224b0 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_shelf.otl @@ -0,0 +1,6 @@ +_tag_calendar_2003 + 2003.otl +_tag_calendar_2004 + 2004.otl +_tag_calendar_2005 + 2005.otl diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ui.sh b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ui.sh new file mode 100755 index 0000000..0d5b911 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_calendar/vo_calendar_ui.sh @@ -0,0 +1,39 @@ +# parent folder of all outlines +OUTLINES=$HOME/Outlines + +# folder for calendar files +# should be a subfolder of $OUTLINES +CALENDAR=$OUTLINES/outline_calendar + +# file for calendar tags +CALENDARTAGS=$CALENDAR/vo_calendar_tags.tag + +# folders to tag for interoutline links and calendar access +# if $CALENDAR is not below $OUTLINES, you need +# TAGFOLDERS=($OUTLINES $CALENDAR) +TAGFOLDERS=($OUTLINES) + +# script to generate calendar skeletons +CALGENSCRIPT=$CALENDAR/vo_calendar_generator.rb + +# option file for ctags +CTAGSOPTIONS=$CALENDAR/vo_calendar_ctags.conf + + +# you should not need to change anything below here +# that's what all the variables above are for +# ------------------------------------------------------------ + +function td() { + local date + date=${1:-`date +%Y-%m-%d`} + ${DISPLAY:+g}vim -c ":ta $date" $CALENDAR/${date%%-*}.otl +} + +function tagvout() { + ctags -f $CALENDARTAGS --options=$CTAGSOPTIONS ${TAGFOLDERS[*]} +} + +function calgen() { + $CALGENSCRIPT $CALENDAR $* +} diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind.py new file mode 100755 index 0000000..99bebf8 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind.py @@ -0,0 +1,198 @@ +#!/usr/bin/python2 + +''' +usage: + freemind.py -o [fmt] , where ofmt selects output format: {otl,mm} + +freemind.py -o otl : + Read in an freemind XML .mm file and generate a outline file + compatable with vim-outliner. +freemind.py -o mm : + Read in an otl file and generate an XML mind map viewable in freemind + +NOTE: + Make sure that you check that round trip on your file works. + +Author: Julian Ryde +''' +import sys +import getopt +import codecs + +import otl +import xml.etree.ElementTree as et +from xml.etree.ElementTree import XMLParser + +debug = False + + +class Outline: # The target object of the parser + depth = -1 + indent = '\t' + current_tag = None + + def start(self, tag, attrib): # Called for each opening tag. + self.depth += 1 + self.current_tag = tag + # print the indented heading + if tag == 'node' and self.depth > 1: + #if 'tab' in attrib['TEXT']: + #import pdb; pdb.set_trace() + print (self.depth - 2) * self.indent + attrib['TEXT'] + + def end(self, tag): # Called for each closing tag. + self.depth -= 1 + self.current_tag = None + + def data(self, data): + if self.current_tag == 'p': + bodyline = data.rstrip('\r\n') + bodyindent = (self.depth - 5) * self.indent + ": " + #textlines = textwrap.wrap(bodytext, width=77-len(bodyindent), + # break_on_hyphens=False) + #for line in textlines: + print bodyindent + bodyline + + def close(self): # Called when all data has been parsed. + pass + + +def mm2otl(*arg, **kwarg): + fname = arg[0][0] + file = codecs.open(fname, 'r', encoding='utf-8') + + filelines = file.readlines() + outline = Outline() + parser = XMLParser(target=outline, encoding='utf-8') + parser.feed(filelines[0].encode('utf-8')) + parser.close() + + +# TODO body text with manual breaks +# TODO commandline arguments for depth, maxlength etc. +# TODO do not read whole file into memory? +# TODO handle decreasing indent by more than one tab +# TODO handle body text lines sometimes not ending with space + +depth = 99 + + +def attach_note(node, textlines): + et.ElementTree + # Format should look like + # + # + # + # + # %s + # + # + # + notenode = et.SubElement(node, 'richcontent') + notenode.set('TYPE', 'NOTE') + htmlnode = et.SubElement(notenode, 'html') + bodynode = et.SubElement(htmlnode, 'body') + for line in textlines: + pnode = et.SubElement(bodynode, 'p') + pnode.text = line + + +def otl2mm(*arg, **kwarg): + fname = arg[0][0] + + # node ID should be based on the line number of line in the + # otl file for easier debugging + #for lineno, line in enumerate(open(fname)): + # enumerate starts at 0 I want to start at 1 + # FIXME freemind.py|107| W806 local variable 'lineno' is assigned to but never used + lineno = 0 + + mapnode = et.Element('map') + mapnode.set('version', '0.9.0') + + topnode = et.SubElement(mapnode, 'node') + topnode.set('TEXT', fname) + + parents = [mapnode, topnode] + + #left_side = True # POSITION="right" + + # read otl file into memory + filelines = codecs.open(fname, 'r', encoding='utf-8') + + # first handle the body texts turn it into a list of headings + # with associated body text for each one this is because the + # body text especially multi-line is what makes it awkward. + headings = [] + bodytexts = [] + for line in filelines: + if otl.is_heading(line): + headings.append(line) + bodytexts.append([]) + else: + # TODO this ': ' removal should go in otl.py? + bodytexts[-1].append(line.lstrip()[2:] + '\n') + + #import pdb; pdb.set_trace() + oldheading = '' + for heading, bodytext in zip(headings, bodytexts): + if debug: + print heading, bodytext + + level = otl.level(heading) + oldlevel = otl.level(oldheading) + + if level == oldlevel: + pass + elif level > oldlevel: + # about to go down in the hierarchy so add this line + # as a parent to the stack + # FIXME freemind.py|149| W802 undefined name 'node' + parents.append(node) + elif level < oldlevel: + # about to go up in the hierarchy so remove parents from the stack + leveldiff = oldlevel - level + parents = parents[:-leveldiff] + + node = et.SubElement(parents[-1], 'node') + node.set('TEXT', heading.lstrip().rstrip('\r\n')) + #if len(bodytext) > 0: + attach_note(node, bodytext) + + oldheading = heading + + xmltree = et.ElementTree(mapnode) + xmltree.write(sys.stdout, 'utf-8') + print + + +def usage(): + print "usage: %s -[mo] " % (sys.argv[0]) + + +def main(): + args = sys.argv + try: + opts, args = getopt.getopt(sys.argv[1:], 'moh', [""]) + except getopt.GetoptError, err: + usage() + print str(err) + sys.exit(2) + + for o, a in opts: + if o == "-m": + otl2mm(args) + elif o == "-o": + mm2otl(args) + elif o == "-h": + usage() + sys.exit(0) + else: + usage() + assert False, "unhandled option: %s" % o + return args + +if __name__ == "__main__": + main() + +# vim: set noet : diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind_outline.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind_outline.py new file mode 100644 index 0000000..5930cfb --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/freemind_outline.py @@ -0,0 +1,48 @@ +#!/usr/bin/python2 +'''Converts a freemind xml .mm file to an outline file compatable with vim +outliner. + +Make sure that you check that round trip on your file works. + +Author: Julian Ryde +''' +import sys +from xml.etree.ElementTree import XMLParser +import textwrap +import codecs + +class Outline: # The target object of the parser + depth = -1 + indent = '\t' + current_tag = None + def start(self, tag, attrib): # Called for each opening tag. + self.depth += 1 + self.current_tag = tag + # print the indented heading + if tag == 'node' and self.depth > 1: + #if 'tab' in attrib['TEXT']: + #import pdb; pdb.set_trace() + print (self.depth-2)*self.indent + attrib['TEXT'] + def end(self, tag): # Called for each closing tag. + self.depth -= 1 + self.current_tag = None + def data(self, data): + if self.current_tag == 'p': + bodyline = data.rstrip('\r\n') + bodyindent = (self.depth-5)*self.indent + ": " + #textlines = textwrap.wrap(bodytext, width=77-len(bodyindent), break_on_hyphens=False) + #for line in textlines: + print bodyindent + bodyline + + def close(self): # Called when all data has been parsed. + pass + +outline = Outline() +parser = XMLParser(target=outline, encoding='utf-8') + +fname = sys.argv[1] +file = codecs.open(fname, 'r', encoding='utf-8') +filelines = file.readlines(); +print "filelines", type(filelines[0]), filelines[0] +parser.feed(filelines[0].encode('utf-8')) +parser.close() diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/otl.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/otl.py new file mode 100644 index 0000000..9268fdc --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/otl.py @@ -0,0 +1,26 @@ +# Some integer IDs +# headings are 1, 2, 3, .... +bodynowrap = -1 # ; +bodywrap = 0 # : + +def level(line): + '''return the heading level 1 for top level and down and 0 for body text''' + if line.lstrip().find(':')==0: return bodywrap + if line.lstrip().find(';')==0: return bodynowrap + strstart = line.lstrip() # find the start of text in lin + x = line.find(strstart) # find the text index in the line + n = line.count("\t",0,x) # count the tabs + return(n+1) # return the count + 1 (for level) + +def is_bodywrap(line): + return level(line) == bodywrap + +def is_bodynowrap(line): + return level(line) == bodynowrap + +def is_heading(line): + return level(line) > 0 + +def is_body(line): + return not is_heading(line) + diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/outline_freemind.py b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/outline_freemind.py new file mode 100755 index 0000000..cea78da --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/outline_freemind.py @@ -0,0 +1,114 @@ +#!/usr/bin/python2 +'''Read in an otl file and generate an xml mind map viewable in freemind + +Make sure that you check that round trip on your file works. + +Author: Julian Ryde +''' + +import sys +import os +import xml.etree.ElementTree as et +import otl +import codecs + +fname = sys.argv[1] +max_length = 40 +depth = 99 + +debug = False + +# TODO body text with manual breaks +# TODO commandline arguments for depth, maxlength etc. +# TODO do not read whole file into memory? +# TODO handle decreasing indent by more than one tab +# TODO handle body text lines sometimes not ending with space + +otlfile = open(fname) +indent = ' ' + +def attach_note(node, textlines): + et.ElementTree + # Format should look like + # + # + # + # + # %s + # + # + # + notenode = et.SubElement(node, 'richcontent') + notenode.set('TYPE', 'NOTE') + htmlnode = et.SubElement(notenode, 'html') + headnode = et.SubElement(htmlnode, 'head') + bodynode = et.SubElement(htmlnode, 'body') + for line in textlines: + pnode = et.SubElement(bodynode, 'p') + pnode.text = line + +# node ID should be based on the line number of line in the otl file for easier +# debugging +#for lineno, line in enumerate(open(fname)): +# enumerate starts at 0 I want to start at 1 +lineno = 0 + +mapnode = et.Element('map') +mapnode.set('version', '0.9.0') + +topnode = et.SubElement(mapnode, 'node') +topnode.set('TEXT', fname) + +parents = [mapnode, topnode] + +#left_side = True # POSITION="right" + +# read otl file into memory +filelines = codecs.open(fname, 'r', encoding='utf-8') + +# remove those that are too deep or body text and pesky end of line characters +#filelines = [line.rstrip('\r\n') for line in filelines if otl.level(line) <= depth] +#filelines = [line for line in filelines if otl.is_heading(line)] + +# first handle the body texts turn it into a list of headings with associated +# body text for each one this is because the body text especially multi-line is +# what makes it awkward. +headings = [] +bodytexts = [] +for line in filelines: + if otl.is_heading(line): + headings.append(line) + bodytexts.append([]) + else: + # TODO this ': ' removal should go in otl.py? + bodytexts[-1].append(line.lstrip()[2:] + '\n') + +#import pdb; pdb.set_trace() +oldheading = '' +for heading, bodytext in zip(headings, bodytexts): + if debug: print heading, bodytext + + level = otl.level(heading) + oldlevel = otl.level(oldheading) + + if level == oldlevel: + pass + elif level > oldlevel: + # about to go down in the hierarchy so add this line as a parent to the + # stack + parents.append(node) + elif level < oldlevel: + # about to go up in the hierarchy so remove parents from the stack + leveldiff = oldlevel - level + parents = parents[:-leveldiff] + + node = et.SubElement(parents[-1], 'node') + node.set('TEXT', heading.lstrip().rstrip('\r\n')) + #if len(bodytext) > 0: + attach_note(node, bodytext) + + oldheading = heading + +xmltree = et.ElementTree(mapnode) +xmltree.write(sys.stdout, 'utf-8') +print diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.otl b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.otl new file mode 100644 index 0000000..dd918c6 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.otl @@ -0,0 +1,27 @@ +A + : This is some early multi-line body text which should wrap. This is some + : early multi-line body text which should wrap. This is some early + : multi-line body text which should wrap. + a + : single line body text + b + 1 + c +B + d + 2 + 3 + 4 +C + +This is a very long heading line that should be longer than the wrap width and so tests this case +Heading with a tab in the middle + : body text with tab in it +Body text with empy line in it + : First line + : + : Third line +Difficult characters + [_] ' " & +Last line body text + : This is a last line of body text diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.sh b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.sh new file mode 100755 index 0000000..15607a1 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/outline_freemind/test.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +tmp=/tmp +dirname=`dirname $0` +fname=$dirname/test.otl +[ -n "$1" ] && fname=$1 + +$dirname/freemind.py -m $fname > $tmp/test.mm +$dirname/freemind.py -o $tmp/test.mm > $tmp/return.otl +diff -Nur $fname $tmp/return.otl diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2html.rb b/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2html.rb new file mode 100644 index 0000000..a4faa03 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2html.rb @@ -0,0 +1,329 @@ +#! /usr/bin/ruby + +# = Synopsis +# +# vo2xo: Converts VIM Outliner files to HTML slides. +# +# = Usage +# +# vo2html [OPTION] input-file +# +# -?, --help: show help +# +# -h, --head file-name: +# insert the contents of the named file within the HTML HEAD element. +# +# -b, --body file-name: +# insert the contents of the named file just after the start of the HTML BODY element. +# +# -t, --tail file-name: +# insert the contents of the named file just before the end the HTML BODY element. +# +# input-file: The VIM Outliner file to be converted. + +# LICENSE +# Copyright (C) 2006 Bruce Perens +# +# This license incorporates by reference the terms of GPL Version 3 or, at +# your choice, any later version of the GPL published by the Free Software +# Foundation, Inc. of Boston, MA, USA. +# +# You may not modify this license. You must preserve it and the accompanying +# copyright declaration in any whole or fragmentary verisons of the software +# to which they apply. +# +require 'getoptlong' +require 'rdoc/usage' +require 'rubygems' +require 'builder' +gem 'ruby-mp3info' +require 'mp3info' + +class OutlineParser +private + LeadingTabPattern = /^(\t*)(.*)$/.freeze + ColonPattern = /^:[ \t]*(.*)$/.freeze + +protected + def initialize(file) + @file = file + @pushback = nil + @nesting = 0 + end + + # Get a line, with push-back. + def get_line + if (line = @pushback) + @pushback = nil + return line + else + return @file.gets + end + end + + # Recursive parser for VIM Outliner. + # + # Meant to be called from itself when nesting increases - it calls its + # callers "nest" method, which calls "parse". This fits well with nesting + # output paradigms like that of Builder::XmlMarkup. + # + # Returns when nesting decreases, or if got_heading is set, just before the + # next top-level heading in the input stream. You should iteratively call + # parse() until more() returns false. This facilitates per-heading handling + # such as in the Xoxo converter, which uses first-level heading to demarcate + # the boundaries of slides. + # + # got_heading: If set, this will return just before the next top-level + # heading, leaving it in the push-back. + # + def parse(got_heading = false) + + while (line = get_line()) + m = line.match(LeadingTabPattern) + n = m[1].length # This line's nesting level. + after_tabs = m[2] # Content after zero or more leading tabs. + + # Drop empty lines, and lines with only tabs. + next if after_tabs == '' + + if n != @nesting # The nesting level changes with this line. + previous = @nesting + @nesting = n + @pushback = line + + # If nesting increases, recursively parse it through nest(). + # If nesting decreases, return to nest(), which will in turn + # return here. Both of these can be true in sequence! Nest() + # detects when a nesting level is closed by looking ahead one + # line and then pushing it back. That line can be one or MORE + # levels lesser than the current nesting level. + # + nest(n) if n > previous + return true if n < previous + elsif + if (p = after_tabs.match(ColonPattern)) and p[1].length > 0 + text(p[1], n) + else + if got_heading and n == 0 + @pushback = line + return true # Return before the next top-level heading. + end + + got_heading = true + heading(after_tabs, n) + end + end + end + false + end + +public +# Simple parser that returns true if there is any remaining content + # and leaves that content in the push-back. + # The return value is the content minus any leading tabs. + # + # Usage + # Return true if there is more content: + # if more + # Return the content of the next line to be read. + # more + # + # The second form is used to get the document title from the first line + # in the file. + # + def more + while (line = get_line()) + if (m = line.match(LeadingTabPattern)) and m[2].length > 0 + @pushback = line + return m[2] + end + end + false + end + +end + +class OutlineToHTML < OutlineParser +private + Type = [ :DOCTYPE, + :html, + :PUBLIC, + '-//W3C//DTD XHTML 1.0 Strict//EN', + 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' + ].freeze + + def wrap(nesting) + if nesting > 1 + @x.li { yield } + else + yield + end + end + +protected + def heading(text, nesting) + if nesting == 0 + @x.h1(text) + else + @x.li(text) + end + end + + def nest(nesting) + wrap(nesting) { @x.ul(:class => "list-#{nesting}") { parse(true) } } + end + + def text(t, nesting) + @x.p(t) + end + +public + def initialize(input_file, head_insert, body_insert, tail_insert) + @head_insert = head_insert.read if head_insert + @body_insert = body_insert.read if body_insert + @tail_insert = tail_insert.read if tail_insert + super(input_file) + end + + def convert + n = 0 + presentation_title = more + + while (title = more) + audio_filename = "#{n + 1}.mp3" + next_audio_filename = "#{n + 2}.mp3" + + @x = ::Builder::XmlMarkup.new(:indent => 2) + @x.declare!(*Type) + @x.html { + body_parameters = {} + + @x.head { + if title != presentation_title + @x.title("#{presentation_title} - #{title}") + else + @x.title("#{presentation_title}") + end + + @x << eval('"' + @head_insert + '"') if @head_insert + + if File.exists?(audio_filename) + seconds = nil + + Mp3Info.open(audio_filename) { |mp3| + seconds = mp3.length.ceil + 1 + } + + parameters = { + :'http-equiv' => 'refresh', + :content => "#{seconds};url=#{n + 2}.html" + } + @x.meta(parameters) + if File.exists?(next_audio_filename) + program = "function Preload() { a = new Image(); a.src = '#{next_audio_filename}'; p = new Image(); p.src = '#{n + 2}.html' }" + @x.script(program, :language => 'JavaScript') + body_parameters[:onload] = "Preload()" + end + end + } + @x.body(body_parameters) { + @x << eval('"' + @body_insert + '"') if @body_insert + attributes = { :class => 'content' } + # Fix: I don't yet know if this is the last slide, so I can't + # decide whether to do this onclick action or not. + # Oops. We have to generate the body tag after its contents. + # This might be awkward to do within Builder. + attributes[:onclick] = "document.location='#{n + 2}.html'" + @x.div(attributes) { + parse(false) + } + @x.div(:class => 'bottom') { + @x << eval('"' + @tail_insert + '"') if @tail_insert + + @x.div(:class => 'navbar-wrapper') { + @x.ul(:class => 'navbar') { + @x.li(:class => 'previous') { + if n > 0 + @x.a('Previous', :href => "#{n}.html") + end + } + + @x.li(:class => 'top') { + @x.a(presentation_title, :href => "1.html") + } + + @x.li(:class => 'next') { + if more + @x.a('Next', :href => "#{n + 2}.html") + end + } + } + } + if File.exists?(audio_filename) + @x.object(:type => 'audio/mpeg', :data => audio_filename, :width => "95%", :height => 42) { + message = "Your web browser isn't configured correctly to play the audio file #{audio_filename}, and thus you are missing the sound-track to this program." + + @x.param(:name => 'autoplay', :value => true) + @x.param(:name => 'playcount', :value => 1) + @x.param(:name => 'showcontrols', :value => false) + @x.param(:name => 'showdisplay', :value => false) + @x.span(message, :class => 'error') + } + end + } + } + } + File.open("#{n += 1}.html", "w") { |f| + f.write(@x.target!) + } + @x = nil + end + end + +end + + +opts = GetoptLong.new( + [ '--help', '-?', GetoptLong::NO_ARGUMENT ], + [ '--head', '-h', GetoptLong::REQUIRED_ARGUMENT ], + [ '--body', '-b', GetoptLong::REQUIRED_ARGUMENT ], + [ '--tail', '-t', GetoptLong::REQUIRED_ARGUMENT ] +) + +head_insert = nil +body_insert = nil +tail_insert = nil + +begin + opts.each do |opt, arg| + case opt + when '--help' + RDoc::usage + when '--head' + head_insert = File.new(arg, 'r') + when '--body' + body_insert = File.new(arg, 'r') + when '--tail' + tail_insert = File.new(arg, 'r') + end + end + + if ARGV.length != 1 + RDoc::usage + exit 0 + end + + input_file = File.new(ARGV[0], 'r') +rescue Exception => error + $stderr.print("Error: #{error}\n") + exit(1) +end + +c = OutlineToHTML.new(input_file, head_insert, body_insert, tail_insert) +if not c.more + $stderr.write("Error: Input file contains no content.\n") + exit(1) +end + +c.convert +exit(0) diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2odp.rb b/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2odp.rb new file mode 100644 index 0000000..963fcf3 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2odp.rb @@ -0,0 +1,415 @@ +#! /usr/bin/ruby + +# = Synopsis +# +# vo2xo: Converts VIM Outliner files to OpenDocument presentations. +# +# = Usage +# +# vo2odp [OPTION] input-file output-file +# +# -?, --help: show help +# +# input-file: The VIM Outliner file to be converted. + +# LICENSE +# Copyright (C) 2006 Bruce Perens +# +# You may apply the terms of GPL Version 3 or, at your choice, any later +# version of the GPL published by the Free Software Foundation, Inc. of +# Boston, MA, USA, to this software. +# +# You may not modify this license. You must preserve it and the accompanying +# copyright declaration in any whole or fragmentary verisons of the software +# to which they apply. +# +require 'getoptlong' +require 'rdoc/usage' +require 'rubygems' +require_gem 'builder' +require_gem 'rubyzip' +require 'zip/zipfilesystem' + +class OutlineParser +private + LeadingTabPattern = /^(\t*)(.*)$/.freeze + ColonPattern = /^:[ \t]*(.*)$/.freeze + +protected + def initialize(file) + @file = file + @pushback = nil + @nesting = 0 + end + + # Get a line, with push-back. + def get_line + if (line = @pushback) + @pushback = nil + return line + else + return @file.gets + end + end + + # Recursive parser for VIM Outliner. + # + # Meant to be called from itself when nesting increases - it calls its + # callers "nest" method, which calls "parse". This fits well with nesting + # output paradigms like that of Builder::XmlMarkup. + # + # Returns when nesting decreases, or if got_heading is set, just before the + # next top-level heading in the input stream. You should iteratively call + # parse() until more() returns false. This facilitates per-heading handling + # such as in the Xoxo converter, which uses first-level heading to demarcate + # the boundaries of slides. + # + # got_heading: If set, this will return just before the next top-level + # heading, leaving it in the push-back. + # + def parse(got_heading = false) + + while (line = get_line()) + m = line.match(LeadingTabPattern) + n = m[1].length # This line's nesting level. + after_tabs = m[2] # Content after zero or more leading tabs. + + # Drop empty lines, and lines with only tabs. + next if after_tabs == '' + + if n != @nesting # The nesting level changes with this line. + previous = @nesting + @nesting = n + @pushback = line + + # If nesting increases, recursively parse it through nest(). + # If nesting decreases, return to nest(), which will in turn + # return here. Both of these can be true in sequence! Nest() + # detects when a nesting level is closed by looking ahead one + # line and then pushing it back. That line can be one or MORE + # levels lesser than the current nesting level. + # + nest(n) if n > previous + return true if n < previous + elsif + if (p = after_tabs.match(ColonPattern)) and p[1].length > 0 + text(p[1], n) + else + if got_heading and n == 0 + @pushback = line + return true # Return before the next top-level heading. + end + + got_heading = true + heading(after_tabs, n) + end + end + end + false + end + +public + # Simple parser that return true if there is any remaining content + # and leaves that content in the push-back. + # The return value is the content minus any leading tabs. + # + # Usage + # Return true if there is more content: + # if more + # Return the content of the next line to be read. + # more + # + # The second form is used to get the document title from the first line + # in the file. + # + def more + while (line = get_line()) + if (m = line.match(LeadingTabPattern)) and m[2].length > 0 + @pushback = line + return m[2] + end + end + false + end + +end + +module OpenDocument +end +module OpenDocument::Presentation +private + DocumentAttributes = { + :'office:version' => '1.0', + :'xmlns:anim' => 'urn:oasis:names:tc:opendocument:xmlns:animation:1.0', + :'xmlns:chart' => 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0', + :'xmlns:dc' => 'http://purl.org/dc/elements/1.1/', + :'xmlns:dom' => 'http://www.w3.org/2001/xml-events', + :'xmlns:dr3d' => 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0', + :'xmlns:draw' => 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0', + :'xmlns:fo' => 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0', + :'xmlns:form' => 'urn:oasis:names:tc:opendocument:xmlns:form:1.0', + :'xmlns:math' => 'http://www.w3.org/1998/Math/MathML', + :'xmlns:meta' => 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0', + :'xmlns:number' => 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0', + :'xmlns:office' => 'urn:oasis:names:tc:opendocument:xmlns:office:1.0', + :'xmlns:ooo' => 'http://openoffice.org/2004/office', + :'xmlns:oooc' => 'http://openoffice.org/2004/calc', + :'xmlns:ooow' => 'http://openoffice.org/2004/writer', + :'xmlns:presentation' => 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0', + :'xmlns:script' => 'urn:oasis:names:tc:opendocument:xmlns:script:1.0', + :'xmlns:smil' => 'urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0', + :'xmlns:style' => 'urn:oasis:names:tc:opendocument:xmlns:style:1.0', + :'xmlns:svg' => 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0', + :'xmlns:table' => 'urn:oasis:names:tc:opendocument:xmlns:table:1.0', + :'xmlns:text' => 'urn:oasis:names:tc:opendocument:xmlns:text:1.0', + :'xmlns:xforms' => 'http://www.w3.org/2002/xforms', + :'xmlns:xlink' => 'http://www.w3.org/1999/xlink', + :'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', + :'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + }.freeze + + + # Bullet style for a particular indentation level. + def bullet_style(x, level, char, space_before, label_width, font_size) + x.tag!('text:list-level-style-bullet', :'text:level' => level, + :'text:bullet-char' => char) { + if level > 1 + x.tag!('style:list-level-properties', + :'text:space-before' => space_before, + :'text:min-label-width' => label_width) + end + x.tag!('style:text-properties', :'fo:font-family' => 'StarSymbol', + :'style:use-window-font-color' => 'true', :'fo:font-size' => font_size) + } + end + + # Paragraph style for a particular level. + def paragraph_style(x, name, left_margin, text_indent) + x.tag!('style:style', :'style:name' => name, + :'style:family' => 'paragraph') { + x.tag!('style:paragraph-properties', :'fo:margin-left' => left_margin, + :'fo:margin-right' => '0cm', :'fo:text-indent' => text_indent) + + } + end + + # Presentation style. + def presentation_style(x, name, parent, min_font_height, additional = {}) + x.tag!('style:style', :'style:name' => name, + :'style:family' => 'presentation', + :'style:parent-style-name' => parent) { + x.tag!('style:graphic-properties', {:'draw:fill-color' => '#ffffff', + :'fo:min-height' => min_font_height}.merge(additional)) + } + end + + # OpenOffice automatic styles. + # I started with a normal output file of OpenOffice, and attempted to compress + # the information: not for efficiency, but to make it understandable. The + # output should be close to identical. + # + def automatic_styles(x) + x.tag!('office:automatic-styles') { + + shared = { :'presentation:display-footer' => 'true', + :'presentation:display-page-number' => 'false', + :'presentation:display-date-time' => 'true' } + + x.tag!('style:style', :'style:name' => 'dp1', :'style:family' => 'drawing-page') { + x.tag!('style:drawing-page-properties', + { :'presentation:background-visible' => 'true', + :'presentation:background-objects-visible' => 'true' }.merge(shared)) + } + x.tag!('style:style', :'style:name' => 'dp2', :'style:family' => 'drawing-page') { + x.tag!('style:drawing-page-properties', + { :'presentation:display-header' => 'true' }.merge(shared)) + } + + x.tag!('style:style', :'style:name' => 'gr1', :'style:family' => 'graphic') { + x.tag!('style:graphic-properties', :'style:protect' => 'size') + } + + presentation_style(x, 'pr1', 'Default-title', '3.256cm') + presentation_style(x, 'pr2', 'Default-outline1', '13.609cm') + presentation_style(x, 'pr3', 'Default-notes', '12.573cm', + :'draw:auto-grow-height' => 'true') + + paragraph_style(x, 'P1', '0cm', '0cm') + paragraph_style(x, 'P2', '1.2cm', '-0.9cm') + paragraph_style(x, 'P3', '0.6cm', '-0.6cm') + + x.tag!('text:list-style', :'style:name' => 'L1') { + 1.upto(9) { |n| + bullet_style(x, n, :'â—', "#{(n - 1) * 0.6}cm", '0.6cm', + '45%') + } + } + x.tag!('text:list-style', :'style:name' => 'L2') { + bullet_style(x, 1, :'â—', '0.6cm', '0.9cm', '45%') + bullet_style(x, 2, :'–', '1.6cm', '0.8cm', '75%') + bullet_style(x, 3, :'â—', '3.0cm', '0.6cm', '45%') + bullet_style(x, 4, :'–', '4.2cm', '0.6cm', '75%') + bullet_style(x, 5, :'â—', '5.4cm', '0.6cm', '45%') + bullet_style(x, 6, :'â—', '6.6cm', '0.6cm', '45%') + bullet_style(x, 7, :'â—', '7.8cm', '0.6cm', '45%') + bullet_style(x, 8, :'â—', '9.0cm', '0.6cm', '45%') + bullet_style(x, 9, :'â—', '10.2cm', '0.6cm', '45%') + } + } + end + +public + def wrap(x) + x.instruct! + x.tag!('office:document-content', DocumentAttributes) { + automatic_styles(x) + x.tag!('office:body') { + x.tag!('office:presentation') { + yield(x) + } + } + } + x + end +end + +class OpenDocument::Manifest +public + def add(path, type) + @files[path] = type + end + + def content + x = Builder::XmlMarkup.new(:indent => 2) + x.instruct! + x.tag!('manifest:manifest', + :'xmlns:manifest' => 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0') { + x.tag!('manifest:file-entry', + :'manifest:media-type' => \ + 'application/vnd.oasis.opendocument.presentation', + :'manifest:full-path' => '/') + @files.each { |k, v| + x.tag!('manifest:file-entry', :'manifest:media-type' => v, + :'manifest:full-path' => k) + } + } + x.target! + end + + def initialize + @files = {} + end +end + +class OutlineToODP < OutlineParser + include OpenDocument::Presentation + +protected + def nest_headings(text, nesting, recurse) + @x.tag!('text:list-item') { + if recurse == 0 + @x.tag!('text:p', :'text:style-name' => "P#{nesting + 1}") { + @x << text + @x << "\n" + } + else + @x.tag!('text:list') { nest_headings(text, nesting, recurse - 1) } + end + } + end + + def heading(text, nesting) + if nesting == 0 + @x.tag!('draw:page', :'draw:name' => text, :'draw:style-name' => 'dp1', + :'draw:master-page-name' => 'Default', + :'presentation:presentation-page-layout-name' => 'AL1T2') { + @x.tag!('draw:frame', :'presentation:style-name' => 'pr1', + :'draw:layer' => 'layout', :'svg:width' => '25.199cm', + :'svg:height' => '3.256cm', :'svg:x' => '1.4cm', :'svg:y' => '0.962cm', + :'presentation:class' => 'title', :'presentation:placeholder' => true) { + @x.tag!('draw:text-box') { + @x.tag!('text:p', :'text:style-name' => 'P1') { + @x << text + @x << "\n" + } + } + } + @x.tag!('draw:frame', :'presentation:style-name' => 'pr2', + :'draw:layer' => 'layout', :'svg:width' => '25.199cm', + :'svg:height' => '13.609cm', :'svg:x' => '1.4cm', :'svg:y' => '4.914cm', + :'presentation:class' => 'outline', :'presentation:placeholder' => true) { + @x.tag!('draw:text-box') { + parse(true) + } + } + } + else + @x.tag!('text:list', :'text:style-name' => 'L2') { + nest_headings(text, nesting, nesting - 1) + } + end + end + + def nest(nesting) + parse(true) + end + + def text(t, nesting) + end + +public + def initialize(input_file) + super(input_file) + end + + def convert + @x = Builder::XmlMarkup.new(:indent => 2) + wrap(@x) { + while more + parse(false) + end + } + @x.target! + end +end + + +opts = GetoptLong.new( + [ '--help', '-?', GetoptLong::NO_ARGUMENT ] +) + +begin + opts.each do |opt, arg| + case opt + when '--help' + RDoc::usage + end + end + + if ARGV.length != 2 + RDoc::usage + exit 0 + end + + input_file = File.new(ARGV[0], 'r') + output_file = Zip::ZipFile.open(ARGV[1], Zip::ZipFile::CREATE) +rescue Exception => error + $stderr.print("Error: #{error}\n") + exit(1) +end + +c = OutlineToODP.new(input_file) +if not c.more + $stderr.write("Error: Input file contains no content.\n") + exit(1) +end + + manifest = OpenDocument::Manifest.new + output_file.file.open('content.xml', 'w') { |f| f.write(c.convert) } + manifest.add('content.xml', 'text/xml') + output_file.dir.mkdir('META-INF') + output_file.file.open('META-INF/manifest.xml', 'w') { |f| + f.write(manifest.content) + } + output_file.close +exit(0) diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2xo.rb b/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2xo.rb new file mode 100644 index 0000000..4c59000 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/vo2xo.rb @@ -0,0 +1,239 @@ +#! /usr/bin/ruby + +# = Synopsis +# +# vo2xo: Converts VIM Outliner files to Xoxo presentations. +# +# = Usage +# +# vo2xo [OPTION] input-file +# +# -?, --help: show help +# +# -b, --body file-name: +# insert the contents of the named file at the start of the HTML BODY element. +# +# -h, --head file-name: +# insert the contents of the named file within the HTML HEAD element. +# +# input-file: The VIM Outliner file to be converted. + +# LICENSE +# Copyright (C) 2006 Bruce Perens +# +# This license incorporates by reference the terms of GPL Version 3 or, at +# your choice, any later version of the GPL published by the Free Software +# Foundation, Inc. of Boston, MA, USA. +# +# You may not modify this license. You must preserve it and the accompanying +# copyright declaration in any whole or fragmentary verisons of the software +# to which they apply. +# +require 'getoptlong' +require 'rdoc/usage' +require 'rubygems' +require_gem 'builder' + +class OutlineParser +private + LeadingTabPattern = /^(\t*)(.*)$/.freeze + ColonPattern = /^:[ \t]*(.*)$/.freeze + +protected + def initialize(file) + @file = file + @pushback = nil + @nesting = 0 + end + + # Get a line, with push-back. + def get_line + if (line = @pushback) + @pushback = nil + return line + else + return @file.gets + end + end + + # Recursive parser for VIM Outliner. + # + # Meant to be called from itself when nesting increases - it calls its + # callers "nest" method, which calls "parse". This fits well with nesting + # output paradigms like that of Builder::XmlMarkup. + # + # Returns when nesting decreases, or if got_heading is set, just before the + # next top-level heading in the input stream. You should iteratively call + # parse() until more() returns false. This facilitates per-heading handling + # such as in the Xoxo converter, which uses first-level heading to demarcate + # the boundaries of slides. + # + # got_heading: If set, this will return just before the next top-level + # heading, leaving it in the push-back. + # + def parse(got_heading = false) + + while (line = get_line()) + m = line.match(LeadingTabPattern) + n = m[1].length # This line's nesting level. + after_tabs = m[2] # Content after zero or more leading tabs. + + # Drop empty lines, and lines with only tabs. + next if after_tabs == '' + + if n != @nesting # The nesting level changes with this line. + previous = @nesting + @nesting = n + @pushback = line + + # If nesting increases, recursively parse it through nest(). + # If nesting decreases, return to nest(), which will in turn + # return here. Both of these can be true in sequence! Nest() + # detects when a nesting level is closed by looking ahead one + # line and then pushing it back. That line can be one or MORE + # levels lesser than the current nesting level. + # + nest(n) if n > previous + return true if n < previous + elsif + if (p = after_tabs.match(ColonPattern)) and p[1].length > 0 + text(p[1], n) + else + if got_heading and n == 0 + @pushback = line + return true # Return before the next top-level heading. + end + + got_heading = true + heading(after_tabs, n) + end + end + end + false + end + +public + # Simple parser that return true if there is any remaining content + # and leaves that content in the push-back. + # The return value is the content minus any leading tabs. + # + # Usage + # Return true if there is more content: + # if more + # Return the content of the next line to be read. + # more + # + # The second form is used to get the document title from the first line + # in the file. + # + def more + while (line = get_line()) + if (m = line.match(LeadingTabPattern)) and m[2].length > 0 + @pushback = line + return m[2] + end + end + false + end + +end + +class OutlineToXoxo < OutlineParser +private + Type = [ :DOCTYPE, + :html, + :PUBLIC, + '-//W3C//DTD XHTML 1.0 Strict//EN', + 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' + ].freeze + + +protected + def heading(text, nesting) + if nesting == 0 + @x.h1(text) + else + @x.li { @x.tag!("h#{nesting + 1}", text) } + end + end + + def nest(nesting) + if nesting == 1 + @x.ul { parse(true) } + else + @x.li(:class => 'nesting') { @x.ul { parse(true) } } + end + end + + def text(t, nesting) + @x.p(t) + end + +public + def initialize(input_file, head_insert, body_insert) + @head_insert = head_insert + @body_insert = body_insert + super(input_file) + end + + def convert + @x = Builder::XmlMarkup.new(:indent => 2) + @x.declare!(*Type) + @x.html { + @x.head { + @x.title(more) + @x << @head_insert.read if @head_insert + } + @x.body { + @x << @body_insert.read if @body_insert + @x.ul { + @x.li(:class => "slide") { parse(false) } while more + } + } + } + @x.target! + end + +end + + +opts = GetoptLong.new( + [ '--help', '-?', GetoptLong::NO_ARGUMENT ], + [ '--body', '-b', GetoptLong::REQUIRED_ARGUMENT ], + [ '--head', '-h', GetoptLong::REQUIRED_ARGUMENT ] +) + +body_insert = nil +head_insert = nil + +begin + opts.each do |opt, arg| + case opt + when '--help' + RDoc::usage + when '--body' + body_insert = File.new(arg, 'r') + when '--head' + head_insert = File.new(arg, 'r') + end + end + + if ARGV.length != 1 + RDoc::usage + exit 0 + end + + input_file = File.new(ARGV[0], 'r') +rescue Exception => error + $stderr.print("Error: #{error}\n") + exit(1) +end + +c = OutlineToXoxo.new(input_file, head_insert, body_insert) +if not c.more + $stderr.write("Error: Input file contains no content.\n") + exit(1) +end + +$stdout.write(c.convert) +exit(0) diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.1 b/pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.1 new file mode 100644 index 0000000..7a1c60b --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.1 @@ -0,0 +1,50 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH vo_maketags 1 "August 13, 2003" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +vo_maketags \- build TAGS for vim outliner +.SH SYNOPSIS +.B vo_maketags +.RI [ filename ] +.SH DESCRIPTION +This manual page documents briefly the +.B vo_maketags +Perl script. +.PP +.B vo_maketags +is a +.BR perl (1) +script that creates tag file which works with +.B vimoutliner +.RB ( vim (1) +plugin for editing outlines). +.SH OPTIONS +.B vo_maketags +script called just with filename of the processed outline, which +is a top of the hierarchy of linked outlines. +.SH SEE ALSO +.BR vim (1) +.ig +.br +The script is fully documented on +.UR http://www.vimoutliner.org +http://www.vimoutliner.org +.UE +.. +.SH AUTHOR +This manual page was written by Matej Cepl , +for the Debian GNU/Linux system (but may be used by others). diff --git a/pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.pl b/pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.pl new file mode 100644 index 0000000..ff6d3ee --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutliner/scripts/votl_maketags.pl @@ -0,0 +1,338 @@ +#!/usr/bin/perl -w +# ####################################################################### +# votl_maketags.pl: Vim outline tagging system, main program, version 0.3.5 +# Copyright (C) 2001-2003, 2011 by Steve Litt (slitt@troubleshooters.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# Steve Litt, slitt@troubleshooters.com, http://www.troubleshooters.com +# ####################################################################### + +# ####################################################################### +# ####################################################################### +# ####################################################################### +# HISTORY +# V0.1.0 Pre-alpha +# Starting at a "top level" indent-defined Vim outline, this +# program finds all "tags" defined as headlines starting with +# _tag_, and containing a subheadline containing the file +# to which the tag should jump. This program creates a tags +# file. +#Steve Litt, 5/28/2001 +#End of version 0.1.0 +# +# V0.1.1 Pre-alpha +# Bug fixes, including ../ resolution +# +#Steve Litt, 5/28/2001 +#End of version 0.1.1 +# +# +# V0.1.2 Pre-alpha +# More bug fixes, and facility to create a new outline +# file from a tag whose corresponding file doesn't yet +# exist. +#Steve Litt, 5/30/2001 +#End of version 0.1.2 +# +# V0.1.3 Pre-alpha +# More bug fixes. This was the first version released +# file from a tag whose corresponding file doesn't yet +# exist. +#Steve Litt, 6/01/2001 +#End of version 0.1.3 +# +# V0.2.0 Pre-alpha +#Steve Litt, 12/03/2002 +# This file unchanged. The overall Vimoutliner version +# 0.2.0 has extensive improvements, including intuitive +# collapse/expand. +#End of version 0.2.0 +#END OF HISTORY +# +# +# V0.1.2 Pre-alpha +# More bug fixes, and facility to create a new outline +# file from a tag whose corresponding file doesn't yet +# exist. +#Steve Litt, 5/30/2001 +#End of version 0.1.2 +# V0.3.5 release 20110303 +# Changed vo_tags.tag directory from +# $HOME/.vimoutliner/ +# to +# $HOME/.vim/vimoutliner/ +#Steve Litt, 3/3/2011 +#End of version 0.3.5 release 20110303 +#END OF HISTORY +# +# ####################################################################### + + +use strict; +use vars qw($TAGFILENAME); +use Cwd; + +$TAGFILENAME = $ENV{"HOME"} . "/.vim/vimoutliner/vo_tags.tag"; +##### OLD LOCATION BELOW, REMOVE IN 0.3.6, COMMENT FOR NOW +#$TAGFILENAME = $ENV{"HOME"} . "/.vimoutliner/vo_tags.tag"; + +sub process1Outline($$); #Early prototype the recursive routine +sub makeDirectory($); #Early prototype the recursive routine + +sub makeTagFileStartingAt($) + { + unless(@ARGV == 1) + { + usage(); + die; + } + my($absoluteFileName) = deriveAbsoluteFileName(Cwd::cwd(), $_[0]); + + my(%processedFiles) = (); + recordFileAsProcessed($absoluteFileName,\%processedFiles); + unlink $TAGFILENAME; + process1Outline($absoluteFileName, \%processedFiles); + sortAndDeleteDupsFromTagFile(); + } + +sub sortAndDeleteDupsFromTagFile() + { + my($TEMPTAGFILENAME) = "$ENV{'HOME'}/temptagfile.tag"; + system("sort $TAGFILENAME | uniq > $TEMPTAGFILENAME"); + system("rm $TAGFILENAME"); + system("mv $TEMPTAGFILENAME $TAGFILENAME"); + } + + +sub process1Outline($$) + { + my($fileName) = $_[0]; + my($processedFilesHashRef) = $_[1]; + + unless(fileExists($fileName)) + { + makeDirectory($fileName); + makeEmptyFile($fileName); + } + + print "Begin processing file $fileName.\n"; + + my($baseDirectory) = getBaseDirectory($fileName); + my(%tags) = getTagsFromFile($fileName); + my(@tagKeys) = keys(%tags); + my($tagKey); + foreach $tagKey (@tagKeys) + { + my($absoluteFileName); + if(isAbsoluteFilePath($tags{$tagKey})) + { + $absoluteFileName = $tags{$tagKey}; + } + else + { + $absoluteFileName = + deriveAbsoluteFileName($baseDirectory, $tags{$tagKey}); + } + appendTagToTagFile($tagKey,$absoluteFileName); + if(notProcessedYet($absoluteFileName, $processedFilesHashRef)) + { + recordFileAsProcessed($absoluteFileName,$processedFilesHashRef); + process1Outline($absoluteFileName, $processedFilesHashRef); + } + } + } + +sub appendTagToTagFile($$) + { + open(TAGFILE, ">>$TAGFILENAME"); + print TAGFILE "$_[0] $_[1] :1\n"; + close(TAGFILE); + } + + +sub makeEmptyFile($) + { + open(OUTLINEFILE, ">" . $_[0]); + close(OUTLINEFILE); + } + + +sub makeDirectory($) + { + my($completeFileName) = $_[0]; + my($directoryName) = ($completeFileName =~ m/^(.*?)[^\/]*$/); + unless($directoryName eq "") + { + my($temp) = ($directoryName =~ m/^(.*).$/); + makeDirectory($temp); + print "Creating $directoryName..."; + if(mkdir $directoryName) + { + print " succeeded.\n"; + } + else + { + print " no action: $!.\n"; + } + } + } + +sub fileExists($) + { + my($outlineFileName) = $_[0]; + my($success) = open(OUTLINEFILE, "<" . $outlineFileName); + if($success) + { + close(OUTLINEFILE); + return(1); + } + else + { + return(0); + } + } + +sub getTagsFromFile($) + { + my($outlineFileName) = $_[0]; + my(%tags); + my($tagString) = ""; + my($success) = open(OUTLINEFILE, "<" . $outlineFileName); + unless($success) + { + print "Failed to open $outlineFileName\n"; + return(()); + } + while() + { + my($line) = $_; + chomp($line); + if($line =~ m/^\s*(_tag_\S+)/) + { + $tagString = $1; + } + elsif($tagString ne "") + { + $line =~ m/^\s*(\S+)/; + my($filename) = $1; + $tags{$tagString} = + deriveAbsoluteFileName(getBaseDirectory($_[0]), $1); + $tagString = ""; + } + } + return(%tags); + } + +sub recordFileAsProcessed($$) + { + my($absoluteFileName) = $_[0]; + my($processedFilesHashRef) = $_[1]; + ${$processedFilesHashRef}{$absoluteFileName} = "1"; + } + +sub notProcessedYet($$) + { + my($absoluteFileName) = $_[0]; + my(%processedFiles) = %{$_[1]}; + if(defined($processedFiles{$absoluteFileName})) + { + return(0); + } + else + { + return(1); + } + } + +sub dia($) + { + print "dia " . $_[0] . "\n"; + } + + +sub isAbsoluteFilePath($) + { + if($_[0] =~ m/^\//) + { + return 1; + } + else + { + return 0; + } + } + +sub getFileNameOnly($) + { + my($fileString); + if ($_[0] =~ m/.+\/(.*)$/) + { + $fileString= $1 + } + else + { + $fileString = $_[0]; + } + + return $fileString; + } + +sub getBaseDirectory($) + { + my($dirString) = ($_[0] =~ m/(.+\/).*$/); + return $dirString; + } + +sub deriveAbsoluteFileName($$) + { + my($absoluteFileName); + my($baseDirectory) = $_[0]; + my($passedFileName) = $_[1]; + unless($baseDirectory =~ m/\/$/) + { + $baseDirectory= $baseDirectory . "/"; + } + if($passedFileName =~ m/^\//) + { + $absoluteFileName = $passedFileName; + } + else + { + $absoluteFileName = $baseDirectory . $passedFileName; + } + + $absoluteFileName =~ s/\/\.\//\//g; #remove all "./"; + deleteDoubleDots($absoluteFileName); + + return($absoluteFileName); + } + +sub deleteDoubleDots($) + { + while($_[0] =~ m/\.\./) + { + $_[0] =~ s/\/[^\/]*\/\.\.//; + } + } + +sub usage() + { + print "\nUsage is:\n"; + print "otltags topLevelOutlineFileName\n\n"; + } + + +makeTagFileStartingAt($ARGV[0]) + diff --git a/pack/acp/start/vimoutliner/vimoutlinerrc b/pack/acp/start/vimoutliner/vimoutlinerrc new file mode 100644 index 0000000..12aaed0 --- /dev/null +++ b/pack/acp/start/vimoutliner/vimoutlinerrc @@ -0,0 +1,67 @@ +"Extra configurations and mappings ****************************************** +"This mapping is fold-level and fold-state dependent +"map dd p +"map dd P + +"Common Plugins +" The vo_modules_load variable holds name of all VO modules you want to load. +" If you do not want to load any VO modules leave it blank + +" This setting loads the checkboxes, tags and smart_paste plugins as default. +let g:vo_modules_load = "checkbox:tags:smart_paste" + +" Uncomment the following line to enable the math plugin. +"let g:vo_modules_load .= ':math' + +" Uncomment the following line to enable new hoisting. +" let g:vo_modules_load .= ':newhoist' + +" Uncomment the following line to enable the format plugin. +"let g:vo_modules_load .= ':format' + +" Uncomment the following line to enable clocking. +"let g:vo_modules_load .= ':clock' + +"User Preferences *************************************************** +"let maplocalleader = ',,' " uncomment for compatibility with + " previous versions of VO + +"setlocal ignorecase " searches ignore case +"setlocal smartcase " searches use smart case +"setlocal wrapmargin=5 +"setlocal tw=78 +"setlocal tabstop=4 " tabstop and shiftwidth must match +"setlocal shiftwidth=4 " values from 2 to 8 work well +"setlocal background=dark " for dark backgrounds +"setlocal nowrap + +" colorscheme votl_light " set a VO specific colorscheme + +"Checkbox Tags +" Tags can contain any word characters (:help word) +" tags must not contain whitespace +" tags must be unique +" there can be no intersections between lists +" 'high', 'High', and 'HIGH' are considered to be unique and nonintersecting +" each sub-list represents a unique circular 'ring' of tags +" currently, these options do not affect checkboxes +" status indicators like DONE, NOT DONE and CANCELED are +" refelected in the checkbox state: [X], [_] and [-], respectively +" each tag is a [] block, just like a checkbox; chosen for possible future integration +" each tag must be delimited by whitespace +" [TODO] [Feature] <-- this +" [TODO][Feature] <-- not this + +let g:cbTags = [ +\ ['TODO','FEEDBACK','VERIFY','DELEGATED','HOLDING'] +\,['Feature','Enhancement','Bug'] +\,['Low','Normal','High','URGENT'] +\,['@Home','@Lab','@Work','@Shopping'] +\] + + +"Hoisting *********************************************************** +"Uncomment and set to 1 to debug hoisting +"let g:hoistParanoia=0 + +" vim: filetype=vim