├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.org ├── meeting-notes ├── 2015-09-22.org ├── 2015-10-21.org ├── 2015-11-18.org ├── 2015-12-16.org ├── 2017-04-20-a.png ├── 2017-04-20-b.png ├── 2017-04-20-c.png ├── 2017-04-20-d.png ├── 2017-04-20-e.png ├── 2017-04-20-f.png ├── 2017-04-20-g.png ├── 2017-04-20-h.png ├── 2017-04-20.org └── 2017-05-18.org ├── support ├── pdx-emacs-small.png ├── pdx-emacs.png └── projector-display.el └── workshops ├── elisp-intro └── talk_1.org ├── keyboard-macros.org ├── org-mode-beginner.org ├── org-mode-gtd-feature-demo.org ├── org-mode-gtd-feature-demo.org_archive ├── org-mode-gtd-sprint-demo.org ├── org-mode-intro ├── for-the-host.el ├── instructions.org ├── sandbox-2.org └── sandbox.org └── org-mode-litp ├── agenda.org ├── for-the-host.el ├── graphics.png ├── instructions.org ├── literate-programming-tangling.png ├── literate-programming-tangling2.png ├── requirements.org ├── sequence-diagram.png ├── tangling-dark.png └── tangling.png /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Contributor Code of Conduct 2 | =========================== 3 | 4 | As contributors and maintainers of this project, and in the interest of 5 | fostering an open and welcoming community, we pledge to respect all 6 | people who contribute through reporting issues, posting feature 7 | requests, updating documentation, submitting pull requests or patches, 8 | and other activities. 9 | 10 | We are committed to making participation in this project a 11 | harassment-free experience for everyone, regardless of level of 12 | experience, gender, gender identity and expression, sexual orientation, 13 | disability, personal appearance, body size, race, ethnicity, age, 14 | religion, or nationality. 15 | 16 | Examples of unacceptable behavior by participants include: 17 | 18 | * The use of sexualized language or imagery 19 | * Personal attacks 20 | * Trolling or insulting/derogatory comments 21 | * Public or private harassment 22 | * Publishing other's private information, such as physical or electronic 23 | addresses, without explicit permission 24 | * Other unethical or unprofessional conduct 25 | 26 | Project maintainers have the right and responsibility to remove, edit, 27 | or reject comments, commits, code, wiki edits, issues, and other 28 | contributions that are not aligned to this Code of Conduct, or to ban 29 | temporarily or permanently any contributor for other behaviors that they 30 | deem inappropriate, threatening, offensive, or harmful. 31 | 32 | By adopting this Code of Conduct, project maintainers commit themselves 33 | to fairly and consistently applying these principles to every aspect of 34 | managing this project. Project maintainers who do not follow or enforce 35 | the Code of Conduct may be permanently removed from the project team. 36 | 37 | This Code of Conduct applies both within project spaces and in public 38 | spaces when an individual is representing the project or its community. 39 | 40 | Instances of abusive, harassing, or otherwise unacceptable behavior may 41 | be reported by contacting a project maintainer at [INSERT EMAIL 42 | ADDRESS]. All complaints will be reviewed and investigated and will 43 | result in a response that is deemed necessary and appropriate to the 44 | circumstances. Maintainers are obligated to maintain confidentiality 45 | with regard to the reporter of an incident. 46 | 47 | This Code of Conduct is adapted from the Contributor Covenant 48 | (http://contributor-covenant.org), version 1.3.0, available at 49 | http://contributor-covenant.org/version/1/3/0/ 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Portland Emacs Hackers Meetup 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2015 Sep 10 5 | #+TAGS: emacs community 6 | 7 | Welcome to the repository of the Portland, Oregon based Meetup 8 | associated with Emacs. 9 | 10 | We get together to share our exciting new discoveries about Emacs and 11 | its multitudinous ecosystem. We also offer assistance to those who 12 | have brought Emacs questions along. 13 | 14 | Both Emacs wizards and Emacs novices are welcome. Even Vim users are 15 | welcome, but we cannot guarantee they will want to remain Vim users at 16 | the end of the session. 17 | 18 | This repository contains documents, notes, and a small collection of 19 | magical incantations related to our organization. 20 | 21 | More to come ... Happy Hacking. 22 | -------------------------------------------------------------------------------- /meeting-notes/2015-09-22.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Notes from the Kickoff 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2015 Sep 22 5 | #+TAGS: emacs community 6 | 7 | I emailed the following message to the entire group yesterday: 8 | 9 | #+BEGIN_QUOTE 10 | Hey there, Hackers! 11 | 12 | Thanks so much for joining the group. I love that we have so much 13 | local interest. I realize that our kickoff/brainstorming session is 14 | starting a bit too quickly for most people, so if you can't meet 15 | tomorrow, but have some ideas/suggestions to pitch, perhaps use 16 | this Discussion page to post them? 17 | 18 | See many of you tomorrow, and the rest of you next month! 19 | Hacker Howard 20 | #+END_QUOTE 21 | 22 | And for those Hackers that came out this evening, /Thanks for 23 | coming!/ I appreciate the feedback and suggestions. Feel free to 24 | submit pull requests to this repository to help correct the 25 | following notes. 26 | 27 | * Introductions 28 | 29 | Attendees for tonight's kickoff included: 30 | 31 | - Howard Abrams, who was hoping to get a group buy on Emacs stickers for his laptop. 32 | - Chris Freeman, who was looking for tips and tricks to using Emacs. 33 | - Will Clifford, who would like to help new people get started and discuss 34 | various workflows surrounding Emacs. 35 | - Micah Cowan, who is an old vi user wanting to switch, but make the 36 | startup time to Emacs quicker... or at least, better integration with tmux. 37 | - William (the other Will) is a seasoned hacker, but new to Emacs. 38 | 39 | * Business 40 | 41 | Monthly, predictable meetings are the best... but when? Chris 42 | Freeman came up a [[http://chrisfreeman.github.io/calagator_2015.html][first pass at a Calagator analysis]]. Meetings are 43 | sorted into reoccurring categories by day of the week and week of 44 | the month. 45 | 46 | We decided that the *Third Wednesday* of each month is the best. 47 | This means that Oct 21st at 6:30pm will be our next meeting. 48 | 49 | * Normal Structure and Agenda 50 | 51 | At EmacsConf 2015, Harry Schwartz mentioned how important it was to 52 | establish a regular /structure/ to each meeting, but what should be 53 | that entail? We discussed quite a few options, including: 54 | 55 | - Larger presentations or tutorials? 56 | - Pro: Very useful and often worthy of recording and transmitting 57 | - Con: Time consuming for the presenter, so hard to get monthly speakers 58 | - Short segments around 15 minutes? 59 | - Pro: Useful, but easier to produce 60 | - Con: Compelling enough to bring people out? 61 | - Lightning talks 62 | - Pro: Very easy to produce 63 | - Con: Can be disjointed, but can we get enough people each month? 64 | - Quick tips and tricks? 65 | - See lightning talks 66 | - Should we do a /Round Table/ that includes “what I’ve learned” 67 | this month? 68 | - Office hours 69 | - Pro: Works well in a bar and can be very focused 70 | - Con: Seems like we aren't trying. ;-) 71 | - New Person's Night 72 | - Similar to Office Hours where people post questions what they 73 | need and others are around to answer. 74 | 75 | We decided to do everything, so next month's agenda will be: 76 | 77 | - 15 minute presentation (we'll start with an Introduction to Magit) 78 | - How to get started. 79 | - The /Why/ one would want to play with the technology. 80 | - How to keep going, including learning resources. 81 | - Lightning talks. 82 | - What did you learn this month? Care to show it off? 83 | - We'll have a before-meeting signup 84 | - Office Hours 85 | - Will, if we can use his office space, will supply a whiteboard 86 | - One side will be problems or other issues one wants to fix 87 | - The other will be other topics or projects that people are 88 | working on. 89 | 90 | * Technical Aspects 91 | 92 | - Find a space with a projector and seating. 93 | - Will going to check with CrowdCompass for space 94 | - Remote viewing? 95 | - Google hangout or other group chat 96 | - Video cameras? 97 | - Decided that we may not have enough attendees to justify this 98 | effort at this time, but that may change. 99 | - Worth summarizing how to get started with Emacs 100 | - Chris Freeman may work on an initial pass at reference links. 101 | - Other more-regular communication? 102 | - IRC channel? #pdx-emacs 103 | - Twitter hashtag? #pdx-emacs 104 | 105 | * Possible Topics 106 | 107 | - Language-specific Tutorials, e.g. Python, Ruby, Clojure 108 | - Invite members of other user groups 109 | - Magit 110 | - Basic tutorial 111 | - New v2.0 features 112 | - org-mode 113 | - Literate programming 114 | - Organizing tasks and agendas 115 | - micro-optimizations 116 | - Beginning tutorials or introductions? 117 | 118 | We decided that Magit would be a great first presentation and Howard 119 | and Will will tag team this one. 120 | -------------------------------------------------------------------------------- /meeting-notes/2015-10-21.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Notes from First Meeting 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2015 Oct 21 5 | #+TAGS: Emacs community 6 | 7 | * Agenda 8 | 9 | - Introductions 10 | - Magit Presentation by Howard Abrams 11 | - Lightning Talks 12 | - Office Hours 13 | - 8pm Transfer to Local Pub 14 | 15 | Thanks to /CrowdCompass/ for Hosting Us! 16 | 17 | * Presentation 18 | 19 | Tonight's presentation was a demonstration on [[https://github.com/magit/magit][Magit]], a Git Porcelain 20 | for Emacs by Howard Abrams. 21 | 22 | Code and presentation is available on Github: 23 | [[http://github.com/howardabrams/magit-demo][www.github.com/howardabrams/magit-demo]] 24 | 25 | Due to technical AV difficulties, we weren't able to record the 26 | presentation, but Howard recorded it at home and uploaded it to 27 | Youtube: https://www.youtube.com/watch?v=vQO7F2Q9DwA 28 | 29 | ** How to Learn? 30 | 31 | Just jump in! =M-x package-install magit= 32 | 33 | #+begin_src emacs-lisp 34 | (require 'magit) 35 | (global-set-key (kbd "C-x g") 'magit-status) 36 | #+end_src 37 | 38 | Clone the demo repo: [[http://github.com/howardabrams/magit-demo][github.com/howardabrams/magit-demo]] 39 | Then run the following commands to create two repositories that 40 | have upstream conflicts. This allows someone to practice the 41 | git workflow (and can be used outside of Magit). 42 | 43 | - =gitrepo-history-conflict.sh= 44 | - =gitrepo-history-nice.sh= 45 | 46 | ** Summary Links 47 | 48 | - Home Page: [[https://github.com/magit/magit][github.com/magit/magit]] 49 | 50 | - Online Tutorials and Books: 51 | - [[http://magit.vc/manual/magit.html#Top][Magit Documentation]] and *Info Mode* 52 | - [[https://www.masteringemacs.org/article/introduction-magit-emacs-mode-git][Mastering Emacs]], by Mickey Peterson 53 | - [[http://daemianmack.com/magit-cheatsheet.html][Magit Cheatsheet]], by Daemian Mack 54 | 55 | - Other Package Integrations: 56 | - *Gerrit*: [[https://github.com/terranpro/magit-gerrit][github.com/terranpro/magit-gerrit]] 57 | - *Github*: [[https://github.com/sigma/magit-gh-pulls][github.com/sigma/magit-gh-pulls]] 58 | 59 | * Lightning Talks 60 | 61 | ** Will discussed Exercism 62 | 63 | The [[http://exercism.io/][exercism.io]] project allows programmers to learn a new language 64 | by solving problems in various languages and submitting them for 65 | review and feedback from peers who have already solved the same problem. 66 | 67 | - Get started by installing the desktop clients (written in Go) 68 | - Use the Emacs plugin that interfaces to the Go client 69 | - Pass the tests by writing the code (Test Driven Development) 70 | - The Emacs Lisp uses the [[http://www.gnu.org/software/emacs/manual/html_mono/ert.html][ert]] 71 | - Once complete, submit, and others can comment on the web site 72 | - Emacs Lisp is one of a learning languages 73 | - Also look at [[https://projecteuler.net/][Project Euler]] and [[https://www.codeeval.com/][CodeEval]] 74 | 75 | ** Other Notes 76 | 77 | - Had a short discussion about the merits of Eshell. 78 | Check out [[http://www.howardism.org/Technical/Emacs/eshell-fun.html][this article]] on it. 79 | 80 | * Office Hours 81 | 82 | Retired to Kell's for beers and to start our Office Hours. Lots of 83 | opinions on org-mode, and we decided that next month, Chris Freeman 84 | will show the best way to get started programming in Python with Emacs. 85 | -------------------------------------------------------------------------------- /meeting-notes/2015-11-18.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Notes from Second Meeting 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2015 Nov 18 5 | #+TAGS: emacs community 6 | 7 | * Agenda 8 | 9 | - Introductions 10 | - Pythonic Interactions with Chris Freeman 11 | - Lightning Talks 12 | - Office Hours 13 | - 8pm Transfer to Local Pub 14 | 15 | Thanks again to /CrowdCompass/ for Hosting Us! 16 | 17 | * Lightning Talks 18 | 19 | ** Editing Macros 20 | 21 | Chris demonstrated visually editing a macro. Really quite 22 | impressive, and would love to see if we can't get him to record the 23 | details. 24 | 25 | ** Quick Text Replacement 26 | 27 | Howard talked about three ways of quickly editing text: 28 | 29 | * *Language-specific Refactorings:* 30 | 31 | Some language modes have nice features for changing code. Started 32 | with demonstrating Magnar Sveen's [[https://github.com/clojure-emacs/clj-refactor.el][Clojure Refactoring]] project for 33 | Cider. 34 | 35 | * *Visual Regular Expressions:* 36 | 37 | Since regular expressions can be tricky to get right the first time 38 | (and Emacs' regular expressions are a bit different than other 39 | interpretations of that spec), Howard uses this project that 40 | highlights what matches and how it will be replaced: 41 | 42 | - Install: =visual-regexp= 43 | - https://github.com/benma/visual-regexp.el/ 44 | - Bind: =C-c r= 45 | 46 | * *Multiple Cursors:* 47 | 48 | Sometimes, the regular expression is going to be too tricky, and 49 | instead of using the macro feature, Magnar Sveen implemented the 50 | ability to have multiple cursors in your document. This becomes 51 | nifty when you want to copy the next two words for each cursor, and 52 | append them to the end each line, but in uppercase... for instance. 53 | 54 | - Install: =multiple-cursors= 55 | - https://github.com/magnars/multiple-cursors.el 56 | 57 | ** Other Notes 58 | 59 | Sacha Chua added our meetup to http://www.emacswiki.org/emacs/Usergroups 60 | 61 | * Office Hours 62 | 63 | Retired to Kell's for drinks and to start our Office Hours. 64 | 65 | Howard demonstrated [[http://geeklet.org/flora/][a side project]] of his for teaching students 66 | about Turing Machines, and Will gave him a couple of links to other 67 | interesting projects: 68 | 69 | - [[http://www.muppetlabs.com/~breadbox/bf/][Brainfuck]] ... a simple Turing language 70 | - [[http://www.nand2tetris.org/][From Nand to Tetris]] ... a course on teaching the basics of computers 71 | -------------------------------------------------------------------------------- /meeting-notes/2015-12-16.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Notes from Third Meeting 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2015 Dec 16 5 | #+TAGS: emacs community 6 | 7 | * Agenda 8 | 9 | - Introductions 10 | - Language Interconnections: 11 | - Pythonic prestidigitation 12 | - Clojure conjuring 13 | - Keyboard Macro Workshop 14 | - Lightning Talks 15 | - Transfer to Local Pub for Office Hours 16 | 17 | Thanks again to /CrowdCompass/ for Hosting Us! 18 | 19 | * Python 20 | 21 | Chris Freeman did a great job of stepping us through an easy 22 | configuration for editing Python in Emacs. 23 | 24 | - Use ELPY as a one stop shop for everything Python. 25 | - Integrates nicely with =company-mode= 26 | - Also integrates with flycheck-mode for lint and other errors 27 | - py-autopep8 will clean up lint-errors on save-buffer 28 | - (elpy-use-ipython) 29 | - (ido-enable-flex-matching t) 30 | 31 | (Chris: I think it would be great just to embed your notes directly 32 | in here) 33 | 34 | * Ruby and Clojure 35 | 36 | As a quick /getting started/ guide for setting up either [[https://github.com/howardabrams/dot-files/blob/master/emacs-ruby.org][Ruby]] or 37 | [[https://github.com/howardabrams/dot-files/blob/master/emacs-clojure.org][Clojure]] using the [[https://github.com/jwiegley/use-package][use-package project]], see the configuration files 38 | in Howard Abrams' [[https://github.com/howardabrams/dot-files][dot-files repository]]. 39 | 40 | * Workshop on Keyboard Macros 41 | 42 | Download the [[https://github.com/howardabrams/pdx-emacs-hackers/blob/master/workshops/keyboard-macros.org][keyboard-macros.org]] file from our group's Github 43 | repository, and follow along the fun in leveling up on keyboard 44 | macros. 45 | 46 | Feedback: While we went through the workshop too quickly, is the 47 | idea good? Is the format useful? Should we do more? 48 | 49 | * Lightning Talks 50 | ** Selective Tangling 51 | 52 | Will Clifford wrote a couple of Emacs functions to determine 53 | whether to tangle an org-mode file block to its source code. 54 | 55 | ** Other Notes 56 | 57 | We have a Google Group: https://groups.google.com/d/forum/emacs-pdx 58 | 59 | Please join this, as we will probably shift from Meetup to using it 60 | for all announcements and discussions. 61 | 62 | * Office Hours 63 | 64 | Once again, we retired to Kell's for continuing discussions. The 65 | following is some notes that I gathered. Feel free to add more... 66 | 67 | ** Symbolic Ligatures 68 | 69 | One conversation that came out of tonight's chatter at Kell's was 70 | doing /symbolic ligatures/ using either [[https://github.com/tonsky/FiraCode][Fira]] or [[https://github.com/i-tu/Hasklig][Hasklig]] fonts and 71 | convert symbols like =->= into a wider arrow symbol in code. 72 | 73 | *Note*: If you use a port of Emacs to the Mac, you can call this 74 | function: 75 | 76 | #+BEGIN_SRC elisp 77 | (mac-auto-operator-composition-mode) 78 | #+END_SRC 79 | 80 | Otherwise, use [[https://github.com/howardabrams/dot-files/blob/master/emacs-client.org#ligatures-in-code][the code located here]]. The end result is normal 81 | symbols in your code, are displayed like: 82 | 83 | [[https://github.com/tonsky/FiraCode/raw/master/showcases/all_ligatures.png]] 84 | 85 | ** Competing with Light Table 86 | 87 | Frank mentioned how he liked a feature in Light Table, where you 88 | could set up a /buffer/ of expressions, and when you modify a 89 | function, it re-evaluates the expressions automatically... yeah, 90 | kinda like running unit tests, but more interactive. 91 | 92 | Without actually seeing Light Table, I (Howard) figured I would 93 | build something similar. I made a really preliminary stab at the 94 | process, but it seems to work. 95 | 96 | Grab the [[https://github.com/howardabrams/dot-files/blob/master/elisp/cider-always-eval.el][source code]] and... well, you probably know what to do with 97 | it. I am curious how helpful this will be. 98 | -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-a.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-b.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-c.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-d.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-e.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-f.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-g.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/meeting-notes/2017-04-20-h.png -------------------------------------------------------------------------------- /meeting-notes/2017-04-20.org: -------------------------------------------------------------------------------- 1 | * Agenda 2 | 3 | - Introductions 4 | - That [[https://pdx-emacs.slack.com/][Slack system]] still working out? 5 | - Workday's Beaverton office is moving... up three floors. Since our 6 | downtown location change has been put on hold, we will continue 7 | to be meeting in Beaverton for a little while longer. 8 | - Hacking on Emacs: Making Breadcrumbs 9 | - Thai Food and drinks 10 | 11 | * Summary of our Hackers Night 12 | 13 | Tonight's goal was to implement a rudimentary, breadcrumb 14 | project. Following a trail of interesting parts of a large code 15 | based using the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Looking-Up-Identifiers.html][standard Xref/Tags system]] always seems to lose my 16 | trail after a little bit, and some of the breadcrumb projects I've 17 | use didn't seem /intuitive/ enough. 18 | 19 | Let's begin with some pre-learned basics: 20 | 21 | - Data Structure? [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Rings.html][Rings]] vs. [[https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html][push and pop]] onto a List 22 | - Useful functions? See =point-marker= and =goto-char= 23 | - Expansion ideas? Should you /advice/ often used functions? 24 | 25 | What follows are Howard's notes, polished for public consumption. 26 | 27 | ** First Attempt 28 | 29 | First, we played around with the built-in Ring data structure that 30 | much of Emacs uses. We created =crumbs=, a ring data structure 31 | and the current index into it, =current-crumb=: 32 | 33 | #+BEGIN_SRC elisp 34 | (defvar crumbs (make-ring 10) "A ring of crumbs, e.g. positions in file buffers.") 35 | (defvar current-crumb 0 "An index into our ring of breadcrumbs.") 36 | #+END_SRC 37 | 38 | To get a [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Overview-of-Markers.html][marker]] (the point position in a file buffer and the name of 39 | the buffer), we call the =point-marker= function, and insert it into 40 | the data structure: 41 | 42 | #+BEGIN_SRC elisp 43 | (defun drop-a-crumb () 44 | (interactive) 45 | (ring-insert crumbs (point-marker))) 46 | #+END_SRC 47 | 48 | (We originally called our ring variable, =ringy= and this function 49 | =droppy=... hey, naming things is hard!) 50 | 51 | To retrieve the mark from the ring structure at a particular point 52 | is straight-forward: 53 | #+BEGIN_SRC elisp 54 | (ring-ref crumbs current-crumb) 55 | #+END_SRC 56 | 57 | But this expression returns a tuple of the buffer and the point 58 | position, so to use this we need to set both values. Our initial 59 | jump-backwards-to-a-previously-dropped-crumb function looked like: 60 | 61 | #+BEGIN_SRC elisp 62 | (defun back-a-crumb () 63 | (interactive) 64 | (let ((mark (ring-ref crumbs current-crumb))) 65 | (pop-to-buffer (marker-buffer mark)) 66 | (goto-char (marker-position mark)) 67 | (setf current-crumb (1- current-crumb)))) 68 | #+END_SRC 69 | 70 | The last line changes the crumb position /backwards/ in our ring 71 | structure. The =ring-ref= function can take any position, as negative 72 | numbers or numbers larger than the contents simply loop back around. 73 | 74 | Of course, this means we should have a /forward/ function: 75 | #+BEGIN_SRC elisp 76 | (defun forward-a-crumb () 77 | (interactive) 78 | (let ((mark (ring-ref crumbs current-crumb))) 79 | (pop-to-buffer (marker-buffer mark)) 80 | (goto-char (marker-position mark)) 81 | (setf current-crumb (1+ current-crumb)))) 82 | #+END_SRC 83 | 84 | This worked reasonably well, but all the functional programmers in 85 | the room, while deeply unhappy about all the /state/ (it is somewhat 86 | inevitable in Emacs Lisp), at least wanted to /hide/ the =crumbs=, so we 87 | added =lexical= scoping and a bit of re-factoring: 88 | 89 | #+BEGIN_SRC elisp 90 | (lexical-let ((crumbs (make-ring 10)) 91 | (current-crumb 0)) 92 | 93 | (defun drop-a-crumb () 94 | (interactive) 95 | ;; Reset the position to match the drop? 96 | (setq current-crumb 0) 97 | (ring-insert crumbs (point-marker))) 98 | 99 | (defun follow-crumb (direction) 100 | (let* ((mark (ring-ref crumbs current-crumb)) 101 | (buf (marker-buffer mark)) 102 | (poit (marker-position mark))) 103 | (pop-to-buffer buf) 104 | (goto-char poit) 105 | (setf current-crumb (funcall direction current-crumb)))) 106 | 107 | (defun back-a-crumb () 108 | (interactive) 109 | (follow-crumb #'1-)) 110 | 111 | (defun forward-a-crumb () 112 | (interactive) 113 | (follow-crumb #'1+))) 114 | #+END_SRC 115 | 116 | ** Inserting into the Trail 117 | 118 | This works in the simplistic case, however it doesn't intuitively 119 | match /our/ expectations. Time for the whiteboard ... 120 | 121 | For instance, what if you had the following breadcrumb trail (let's 122 | give them symbolic names for some positions in buffers): 123 | 124 | #+BEGIN_SRC dot :file 2017-04-20-a.png :cmdline -Kdot -Tpng :exports results :results silent 125 | digraph G { 126 | rankdir=LR; 127 | a -> b -> c -> d -> e 128 | } 129 | #+END_SRC 130 | 131 | [[file:2017-04-20-a.png]] 132 | 133 | Let's move into the middle of this breadcrumb trail 134 | by pointing the /current/ variable: 135 | 136 | #+BEGIN_SRC dot :file 2017-04-20-b.png :cmdline -Kdot -Tpng :exports results :results silent 137 | digraph G { 138 | rankdir=LR; 139 | a -> b -> c -> d -> e 140 | node [label="Current" shape=box] current 141 | current -> c 142 | {rank=same; current c} 143 | } 144 | #+END_SRC 145 | 146 | [[file:2017-04-20-b.png]] 147 | 148 | What should happen if we drop a new crumb (=f=)? With a ring, it 149 | either appends or pre-pends it on this list (which, for a ring, is 150 | essentially the same thing). If we didn't change our current 151 | position, our structure looks like: 152 | 153 | #+BEGIN_SRC dot :file 2017-04-20-c.png :cmdline -Kdot -Tpng :exports results :results silent 154 | digraph G { 155 | rankdir=LR; 156 | a -> b -> c -> d -> e -> f 157 | node [label="Current" shape=box] current 158 | current -> c 159 | {rank=same; current c} 160 | } 161 | #+END_SRC 162 | 163 | [[file:2017-04-20-c.png]] 164 | 165 | With this, if when we move back on the crumby trail, we end 166 | at =b= (which probably has no relationship with =f)=. However, if we 167 | update the current pointer when we append the new mark, our 168 | structure looks like: 169 | 170 | #+BEGIN_SRC dot :file 2017-04-20-d.png :cmdline -Kdot -Tpng :exports results :results silent 171 | digraph G { 172 | rankdir=LR; 173 | a -> b -> c -> d -> e -> f 174 | node [label="Current" shape=box] current 175 | current -> f 176 | {rank=same; current f} 177 | } 178 | #+END_SRC 179 | 180 | [[file:2017-04-20-d.png]] 181 | 182 | But now, going backwards goes to =e=, which again, probably has 183 | nothing to do with the new mark, and is even further away from =c= 184 | (where we came from to set this new mark). While it seems 185 | counter-intuitive to program, perhaps when we drop a crumb, we also 186 | increase the counter from where we last were (=c=): 187 | 188 | #+BEGIN_SRC dot :file 2017-04-20-e.png :cmdline -Kdot -Tpng :exports results :results silent 189 | digraph G { 190 | rankdir=LR; 191 | a -> b -> c -> d -> e -> f 192 | node [label="Current" shape=box] current 193 | current -> d 194 | {rank=same; current d} 195 | } 196 | #+END_SRC 197 | 198 | [[file:2017-04-20-e.png]] 199 | 200 | Now we can go backward to =c=, but finding =f= would be difficult, as 201 | it may not be anywhere near =c=. 202 | What we would expect is a mark that is /inserted/: 203 | 204 | #+BEGIN_SRC dot :file 2017-04-20-f.png :cmdline -Kdot -Tpng :exports results :results silent 205 | digraph G { 206 | rankdir=LR; 207 | a -> b -> c -> f -> d -> e 208 | node [label="Current" shape=box] current 209 | current -> f 210 | {rank=same; current f} 211 | } 212 | #+END_SRC 213 | 214 | [[file:2017-04-20-f.png]] 215 | 216 | Now, if we try to go backward along our breadcrumb trail, we would 217 | go back to =c= (which is intuitive), and forward from =c= goes to =f= 218 | (expected). /Forward again/? This would go to =d=, and while this may 219 | not be really associated with the new mark, it is at least close 220 | enough in the mind of the breadcrumb dropper. 221 | 222 | At least, this seemed more intuitive to us after a bit of whiteboarding. 223 | 224 | ** Breadcrumb Relationship 225 | 226 | [[https://twitter.com/wobher][William Clifford‏]] thought we should model (and store) the 227 | /relationships/ of the "dropped marks". 228 | 229 | #+BEGIN_SRC dot :file 2017-04-20-g.png :cmdline -Kdot -Tpng :exports results :results silent 230 | digraph G { 231 | rankdir=LR; 232 | d1 [label="d"] 233 | c1 [label="c"] 234 | b1 [label="b"] 235 | a1 [label="a"] 236 | b1 -> c 237 | c1 -> d 238 | d1 -> e 239 | a1 -> b 240 | } 241 | #+END_SRC 242 | 243 | [[file:2017-04-20-g.png]] 244 | 245 | At this point =e= doesn't /point/ to anything, so going /forward/ doesn't 246 | make sense, but normally, jumping /forward/ means jumping to the /value/ 247 | associated with the current mark (on the left side in the diagram). 248 | 249 | If the current position is =c=, when we move around and /drop/ a new 250 | breadcrumb, we /insert/ the new mark, =f=, by: 251 | 252 | - Replacing the value associated with =c= to the new mark, and 253 | - Add the new mark that is associated with =c='s old value: 254 | 255 | #+BEGIN_SRC dot :file 2017-04-20-h.png :cmdline -Kdot -Tpng :exports results :results silent 256 | digraph G { 257 | rankdir=LR; 258 | d1 [label="d"] 259 | f1 [label="f" color="green"] 260 | c1 [label="c"] 261 | f [color="green"] 262 | b1 [label="b"] 263 | a1 [label="a"] 264 | a1 -> b 265 | b1 -> c 266 | c1 -> f [color="green"] 267 | f1 -> d [color="green"] 268 | d1 -> e 269 | } 270 | #+END_SRC 271 | 272 | [[file:2017-04-20-h.png]] 273 | 274 | Yeah, I immediately started jumping to maps as well. Let's 275 | implement this structure with an [[info:elisp#Association%20Lists][Association List]] to store our 276 | sequence of 5 /relationship/ marks: 277 | 278 | #+BEGIN_SRC elisp 279 | ( ( :a . :b ) 280 | ( :b . :c ) 281 | ( :c . :d ) 282 | ( :d . :e ) ) 283 | #+END_SRC 284 | 285 | With this, jumping /forward/ means jumping to the =assoc= of the current 286 | key point, and going /backward/ means jumping to the =rassoc= of the 287 | current key. And to /drop/ a new breadcrumb, =:f=, we: 288 | 289 | - =rassoc= the value of =:c= (that is, =:d=) to be the new value 290 | destination of the new mark, e.g. =( :f . :d )= 291 | - =assoc= the =:c= to the new current mark, e.g. =( :c . :f )= 292 | 293 | Our end result would be: 294 | #+BEGIN_SRC elisp 295 | ( ( :a . :b ) 296 | ( :b . :c ) 297 | ( :c . :f ) 298 | ( :f . :d ) 299 | ( :d . :e ) ) 300 | #+END_SRC 301 | 302 | I'll let the implementation of this be an exercise to the reader, as 303 | I had another idea... 304 | 305 | ** Inserting into a List 306 | 307 | At this point, our hacking fun came to an end, and we left to have a 308 | round at a local Thai place. Traveling home on train, I got to 309 | trying the idea of /inserting/ into simple list... 310 | 311 | Let's go back to our breadcrumb trail represented as a list of 312 | symbols: 313 | #+BEGIN_SRC elisp 314 | (setq crumbs '(:a :b :c :d :e)) 315 | #+END_SRC 316 | 317 | We represent the =current-crumb= as an index where =0= would be 318 | pointing to the first location, =:a=, and if we had moved back to =:c=, 319 | our =current-crumb= as =2=. 320 | 321 | If we wanted to insert =:f=, we want a function with this behavior: 322 | 323 | #+BEGIN_SRC elisp 324 | (list-insert '(:a :b :c :d :e) 2 :f) ; => (:a :b :c :f :d :e) 325 | (list-insert '(:a :b :c :d :e) 0 :f) ; => (:a :f :b :c :d :e) 326 | (list-insert '(:a :b :c :d :e) 4 :f) ; => (:a :b :c :d :e :f) 327 | #+END_SRC 328 | 329 | Since the list will never be /that/ long, we could make a function 330 | that creates a new list with an element inserted /after/ some point. 331 | 332 | #+BEGIN_SRC elisp 333 | (defun list-insert (lst index element) 334 | "Insert ELEMENT into the list, LIST, at INDEX, where pos == 0 would be insert." 335 | ;; The calculated position is based on the behavior of `last' and `last' 336 | (let ((pos (1- (- (length lst) index)))) 337 | 338 | (append (butlast lst pos) ; First section 339 | (list element) ; Element as a list 340 | (last lst pos)))) ; Second section 341 | #+END_SRC 342 | 343 | What about the extreme case of starting out? 344 | #+BEGIN_SRC elisp 345 | (list-insert () 0 :a) ; => (:a) 346 | #+END_SRC 347 | Actually, with an empty list, the index really doesn't matter: 348 | #+BEGIN_SRC elisp 349 | (list-insert () -1 :a) ; => (:a) 350 | #+END_SRC 351 | 352 | ** Intuitive Breadcrumbs 353 | 354 | Let's re-factor our original breadcrumbs to use our new =list-insert= 355 | function: 356 | 357 | #+BEGIN_SRC elisp 358 | (lexical-let ((crumbs (list)) 359 | (current-crumb 0)) 360 | 361 | (defun drop-a-crumb () 362 | (interactive) 363 | (setq crumbs 364 | (list-insert crumbs current-crumb (point-marker))) 365 | (setq current-crumb (1+ current-crumb))) 366 | 367 | (defun follow-crumb () 368 | (if crumbs 369 | (let* ((mark (nth current-crumb crumbs)) 370 | (buf (marker-buffer mark)) 371 | (poit (marker-position mark))) 372 | (pop-to-buffer buf) 373 | (goto-char poit)))) 374 | 375 | (defun back-a-crumb () 376 | (interactive) 377 | (if (> current-crumb 0) 378 | (setq current-crumb (1- current-crumb))) 379 | (follow-crumb)) 380 | 381 | (defun forward-a-crumb () 382 | (interactive) 383 | (if (< current-crumb (1- (length crumbs))) 384 | (setq current-crumb (1+ current-crumb))) 385 | (follow-crumb))) 386 | #+END_SRC 387 | 388 | This works really well, except for when you want to go forward to a 389 | crumb, but the point is already there. Seems that it should honor 390 | the wish and move forward one more time. But now that the hack night 391 | is over, I [[https://github.com/howardabrams/dot-files/blob/master/elisp/better-breadcrumbs.el][tweaked this for my own shaved yak]] which I hope to 392 | demonstrate next month. 393 | -------------------------------------------------------------------------------- /meeting-notes/2017-05-18.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Notes from Hack Night 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2017 May 10 5 | #+TAGS: emacs hacking 6 | 7 | * Welcome Hackers 8 | *to the Mystical Order of Emacs* 9 | 10 | - Introductions 11 | 12 | - Meeting Announcements: 13 | - Are [[http://calagator.org/events/1250471899][Calagator Announcements]] sufficient? 14 | - Ideas for Improving our [[https://pdx-emacs.slack.com/][Slack Community]]? 15 | - Ideas for Improving our Emacs Outreach 16 | through our [[https://github.com/howardabrams/pdx-emacs-hackers][Github project]]? 17 | - Location? Ideas to move back downtown? 18 | - Virtual or streaming meetings a good idea? 19 | 20 | - Lightning Talks: [[https://github.com/howardabrams/dot-files/blob/master/elisp/better-breadcrumbs.el][Breadcrumb Implementations]] 21 | 22 | - Hack Night: Automatic purging of old tasks 23 | 24 | - Office Hours: Siam Lotus 25 | 26 | * Notes 27 | -------------------------------------------------------------------------------- /support/pdx-emacs-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/support/pdx-emacs-small.png -------------------------------------------------------------------------------- /support/pdx-emacs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/support/pdx-emacs.png -------------------------------------------------------------------------------- /support/projector-display.el: -------------------------------------------------------------------------------- 1 | ;;; PROJECTOR-DISPLAY --- Display the Agenda for Meetings 2 | ;; 3 | ;; Author: Howard Abrams 4 | ;; Copyright © 2015, Howard Abrams, all rights reserved. 5 | ;; Created: 12 Dec 2015 6 | ;; 7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 8 | ;; 9 | ;;; Commentary: 10 | ;; 11 | ;; Run the function, `pdx-display' and it will load or generate an 12 | ;; agenda for displaying the logo and whatnot at a meeting. 13 | ;; 14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 15 | ;; 16 | ;;; Change log: 17 | ;; 18 | ;; 19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20 | ;; 21 | ;; This program is free software; you can redistribute it and/or 22 | ;; modify it under the terms of the GNU General Public License as 23 | ;; published by the Free Software Foundation; either version 3, or 24 | ;; (at your option) any later version. 25 | ;; 26 | ;; This program is distributed in the hope that it will be useful, 27 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 | ;; General Public License for more details. 30 | ;; 31 | ;; You should have received a copy of the GNU General Public License 32 | ;; along with this program; see the file COPYING. If not, write to 33 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth 34 | ;; Floor, Boston, MA 02110-1301, USA. 35 | ;; 36 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 37 | ;; 38 | ;;; Code: 39 | 40 | (when (not (require 'use-package nil t)) 41 | (package-install 'use-package)) 42 | 43 | (use-package demo-it 44 | :ensure t) 45 | 46 | 47 | (defun pdx-emacs-display () 48 | "Display the PDX Emacs Hackers logo and agenda." 49 | (interactive) 50 | (let* ((year (format-time-string "%Y")) 51 | (month (format-time-string "%m")) 52 | (day (format-time-string "%d")) 53 | (file-pattern (format "../meeting-notes/%s-%s\*.org" year month)) 54 | (exist-file (car (file-expand-wildcards file-pattern))) 55 | (file-name (format "../meeting-notes/%s-%s-%s.org" year month day))) 56 | 57 | (find-file "pdx-emacs.png") 58 | (demo-it-hide-mode-line) 59 | (split-window) 60 | (other-window 1) 61 | (org-tree-slide-simple-profile) 62 | (if (file-exists-p exist-file) 63 | (demo-it-presentation exist-file) 64 | (demo-it-presentation file-name)))) 65 | 66 | (pdx-emacs-display) 67 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 68 | ;;; projector-display.el ends here 69 | -------------------------------------------------------------------------------- /workshops/elisp-intro/talk_1.org: -------------------------------------------------------------------------------- 1 | #+TITLE: "Introducing" Elisp Programming 2 | #+DATE: <2016-07-21 Thu> 3 | #+AUTHOR: William Clifford 4 | #+EMAIL: wobh@yahoo.com 5 | #+EMAIL: twitter: @wobher 6 | 7 | * About this talk :about: 8 | 9 | - After the Elisp tutorial 10 | - Before your first serious Elisp project 11 | 12 | * Useful preliminaries :about: 13 | 14 | - Basic Lisp syntax 15 | - s-expressions ("prefix notation") 16 | - ~(+ 1 2)~ 17 | - cons cells ~cons~, ~car~, ~cdr~ 18 | - as trees ~(equal '(0 . (1 . 2)) (list (cons 0 (cons 1 2))))~ 19 | - as lists ~(equal (list 0 1 2) (cons 0 (cons 1 (cons 2 nil))))~ 20 | - Elisp tutorial 21 | - Useful extensions of elisp in ~cl~ package 22 | - widely required, probably loaded already 23 | - implements a large subset of Common Lisp 24 | - can refer to the Common Lisp Hyperspec 25 | 26 | * Plan :plan: 27 | 28 | - step-by-step write a client to a simple web API 29 | 30 | * Steps :plan: 31 | 32 | 1. Get documentation for target API 33 | 2. Setup tests 34 | 3. Make requests 35 | 4. Parse responses 36 | 5. Setup package 37 | 38 | * Part n of m :plan: 39 | 40 | - Unlikely to get through all these steps. 41 | 42 | * Get documentation for target API :docs:api: 43 | 44 | - Data.gov 45 | 46 | - API: [[https://www.data.gov/developers/api]] 47 | - base URL: http://catalog.data.gov/api/3/ 48 | 49 | - API docs: http://docs.ckan.org/en/latest/ 50 | - Demo URL: http://demo.ckan.org/api/3/ 51 | 52 | * "Test first" :tests: 53 | 54 | - controversy! 55 | 56 | * "Test first" Thesis :tdd:tests: 57 | 58 | - prioritizes fundamental questions 59 | - scientific 60 | - (other virtues) 61 | 62 | * "Test first" Antithesis :tdd:tests: 63 | 64 | - +premature+ prenatal formalization 65 | - expensive refactoring 66 | - proceedural 67 | - (other complaints) 68 | 69 | * "Test first" Synthesis :tdd:tests: 70 | 71 | Three middle paths 72 | 73 | - "spike" 74 | - exploratory implementation 75 | 76 | - informal testing with REPLs 77 | - for elisp, use the *scratch* buffer 78 | - =C-x C-e= :: evaluates expression, sends results to minibuffer 79 | - =C-u C-x C-e= :: evaluates expression, sends results to current buffer 80 | 81 | - use a lightweight test framework to reduce formal requirements 82 | - for elisp, use ERT 83 | 84 | * How lightweight? :ert:tests: 85 | 86 | - lightish 87 | 88 | * Documentation :docs:ert:tests: 89 | 90 | - [[info:ert]] 91 | - ~M-x ert RET t RET~ :: runs all tests 92 | - results in ~*ert*~ buffer 93 | 94 | #+BEGIN_SRC elisp 95 | (require 'ert) 96 | 97 | (ert-deftest data-gov-test-catalog () 98 | "Test getting catalog from data.gov" 99 | (should (equal "" 100 | (data-gov-catalog)))) 101 | #+END_SRC 102 | 103 | * Uh-oh :ert:tests: 104 | 105 | - we should mock the API response 106 | - how do we do that? 107 | - how do we even make requests? 108 | 109 | * Making HTTP requests :http: 110 | 111 | two choices: 112 | 113 | - use ~request~ package 114 | - use this one 115 | 116 | - use ~url~ package 117 | - don't use this one 118 | - for reals, use ~request~ 119 | 120 | * Why the ~url~ package? :url:http: 121 | 122 | - Primitive 123 | - Difficult 124 | - We'll learn more 125 | 126 | * ~url~ documentation :docs:url:http: 127 | 128 | - info:url 129 | - parse urls into lisp data structures 130 | - make HTTP requests 131 | 132 | * Parsing URLs :uris:url:http: 133 | 134 | - info:url#URI%2520Parsing 135 | 136 | #+NAME: parsing+printing_urls 137 | #+BEGIN_SRC elisp 138 | (url-generic-parse-url "http://demo.ckan.org/api/3/action/group_show?id=data-explorer") 139 | 140 | [cl-struct-url "http" nil nil "demo.ckan.org" nil "/api/3/action/group_show?id=data-explorer" nil nil t nil t] 141 | 142 | (url-recreate-url [cl-struct-url "http" nil nil "demo.ckan.org" nil "/api/3/action/group_show?id=data-explorer" nil nil t nil t]) 143 | 144 | "http://demo.ckan.org/api/3/action/group_show?id=data-explorer" 145 | #+END_SRC 146 | 147 | #+NAME: example testing urls 148 | #+BEGIN_SRC elisp 149 | (require 'ert) 150 | (require 'url) 151 | 152 | (ert-deftest url-test-parse-print-urls () 153 | "Test parsing and printing of URLs." 154 | (let ((subject "http://demo.ckan.org/api/3/action/group_show?id=data-explorer") 155 | (results [cl-struct-url "http" nil nil "demo.ckan.org" nil "/api/3/action/group_show?id=data-explorer" nil nil t nil t])) 156 | (should (equal results 157 | (url-generic-parse-url subject))) 158 | (should (equal subject 159 | (url-recreate-url results))))) 160 | #+END_SRC 161 | 162 | * URL structures :uris:url:http: 163 | - [[info:url#Parsed%20URIs]] 164 | 165 | #+NAME: parsed-uris 166 | #+BEGIN_SRC elisp 167 | (ert-deftest url-test-parse-url-parts () 168 | "Test url slot reader functions." 169 | (let ((subject (url-generic-parse-url 170 | "https://demo.ckan.org/api/3/action/group_show?id=data-explorer"))) 171 | (should (equal "https" 172 | (url-type subject))) 173 | (should (equal nil 174 | (url-user subject))) 175 | (should (equal nil 176 | (url-password subject))) 177 | (should (equal 443 178 | (url-port subject))) 179 | (should (equal "/api/3/action/group_show?id=data-explorer" 180 | (url-filename subject))) 181 | (should (equal nil 182 | (url-target subject))) 183 | (should (equal t 184 | (url-fullness subject))))) 185 | #+END_SRC 186 | 187 | * URL encoding :uris:url:http: 188 | - [[info:url#URI%20Encoding]] 189 | 190 | #+NAME: encoding-uris 191 | #+BEGIN_SRC el 192 | (ert-deftest url-test-encode-corrects-case () 193 | "url-encode-url should downcase case-indifferent parts of url." 194 | (let ((subject "HTTP://DEMO.CKAN.ORG/API/3/ACTION/GROUP_SHOW?ID=DATA-EXPLORER")) 195 | (should (equal "http://demo.ckan.org/API/3/ACTION/GROUP_SHOW?ID=DATA-EXPLORER" 196 | (url-encode-url subject))))) 197 | 198 | (ert-deftest url-test-encode-hexifies () 199 | "url-encode-url should hexify were necessary." 200 | (let ((subject "http://www.example.com/foo?bar baz")) 201 | (should (equal "http://www.example.com/foo?bar%20baz") 202 | (url-encode-url subject)))) 203 | 204 | (ert-deftest url-test-hexify-string () 205 | "url-hexify-string should hexify string" 206 | (let ((subject "foo?bar baz") 207 | (results "foo%3Fbar%20baz")) 208 | (should (equal results (url-hexify-string subject))))) 209 | 210 | (ert-deftest url-test-unhex-string () 211 | "url-unhex-string should unhex string" 212 | (let ((subject "foo%3Fbar%20baz") 213 | (results "foo?bar baz")) 214 | (should (equal results (url-unhex-string subject))))) 215 | #+END_SRC 216 | 217 | * Create URL with a simple ~make-url~ package :uris:url:http: 218 | 219 | #+NAME: make-url 220 | #+BEGIN_SRC elisp 221 | ;; TODO: use RFC 3986 templates 222 | 223 | (defun make-url-domain (&rest names) 224 | (mapconcat 'identity names ".")) 225 | 226 | (defun make-url-path (&rest names) 227 | (mapconcat 'identity names "/")) 228 | 229 | (defun make-url-query (&rest fields) 230 | (mapconcat 'identity fields "&")) 231 | 232 | (defun make-url-query-field (field-key field-val) 233 | (format "%s=%s" field-key field-val)) 234 | 235 | (provide 'make-url) 236 | #+END_SRC 237 | 238 | * URL Queries :uris:url:http: 239 | 240 | - ~url-filename~ includes the query part. 241 | - makes composing queries irritating 242 | - can we make an accessor for it? 243 | - use ~setf~ macro to set the query portion of ~url-filename~ 244 | 245 | * ~url-query~ usage example :uris:url:http: 246 | 247 | #+NAME: url-query-example-usage 248 | #+BEGIN_SRC elisp 249 | (defun wikipedia-api-url (pageid &optional lang) 250 | (let ((url (url-generic-parse-url ""))) 251 | (setf (url-host url) (make-url-domain (or lang "en") 252 | "wikipedia" 253 | "org") 254 | (url-filename url) (make-url-path "w" 255 | "api.php") 256 | (url-query url) (make-url-query "action=query" 257 | "prop=extracts" 258 | (make-url-query-field "pageids" 259 | pageid) 260 | "explaintext" 261 | "format=json")))) 262 | #+END_SRC 263 | 264 | * ~url-query~ tests :uris:url:http: 265 | 266 | #+NAME: url-query-tests 267 | #+BEGIN_SRC elisp 268 | (require 'ert) 269 | 270 | (ert-deftest url-query-test () 271 | "Test of uri-query association" 272 | (let ((subject (url-generic-parse-url 273 | "http://example.com/foo?bar=1&baz=2#qux"))) 274 | (should (equal "bar=1&baz=2" 275 | (url-query subject))))) 276 | 277 | (ert-deftest set-url-query-test () 278 | (let ((subject (url-generic-parse-url 279 | "http://example.com/foo?bar=1&baz=2#qux"))) 280 | (setf (url-query subject) "baz=3&bar=5") 281 | (should (equal "/foo?baz=3&bar=5" 282 | (url-filename subject))))) 283 | #+END_SRC 284 | 285 | * ~url-query~ accessor :uris:url:http: 286 | 287 | #+NAME: url-query-accessor 288 | #+BEGIN_SRC elisp 289 | (defun url-query (url) 290 | "Extract query portion of URL." 291 | (let ((url-fn (url-filename url))) 292 | (substring url-fn 293 | (1+ (string-match "?" url-fn))))) 294 | 295 | (defun set-url-query (url qry) 296 | "Set query portion of URL." 297 | (let ((url-fn (url-filename url))) 298 | (setf (url-filename url) 299 | (with-temp-buffer 300 | (insert url-fn) 301 | (goto-char (point-min)) 302 | (search-forward "?") 303 | (delete-region (point) (point-max)) 304 | (insert qry) 305 | (buffer-string))))) 306 | 307 | (gv-define-simple-setter url-query set-url-query) 308 | #+END_SRC 309 | 310 | * How to make HTTP requests :req:url:http: 311 | 312 | - [[info:url#Retrieving%20URLS]] 313 | - Function: ~url-retrieve~ url callback &optional cbargs silent 314 | - Function: ~url-retrieve-synchronously~ url 315 | 316 | * What about ~url-queue-retrieve~? :req:url:http: 317 | 318 | - forget it exists 319 | 320 | * ~url-http-options~ useless? :options:req:url:http: 321 | 322 | - [[info:url#HTTP%20URL%20Options]] 323 | 324 | #+NAME: url-options 325 | #+BEGIN_SRC elisp 326 | (url-http-options "https://api.bufferapp.com/") 327 | 328 | nil 329 | 330 | (url-http-options "https://en.wikipedia.org/w/api.php") 331 | 332 | nil 333 | 334 | (url-http-options "http://apache.org/dist/httpd") 335 | 336 | nil 337 | #+END_SRC 338 | 339 | * wat :req:url:http: 340 | 341 | - ~url-retrieve~'s callback can be called any number of times 342 | - always check and dispatch on call status in callback 343 | 344 | * Missing documentation :docs:req:url:http: 345 | 346 | - [[info:url#Customization]] 347 | - [[info:url#Variable%20Index]] 348 | - https://www.emacswiki.org/emacs/UrlPackage 349 | - https://www.rosettacode.org/wiki/HTTP#Emacs_Lisp 350 | - http://emacs.stackexchange.com/questions/12464/go-to-body-after-url-retrieve-synchronously 351 | - https://frozenlock.org/tag/url-retrieve/ 352 | - https://frozenlock.org/2012/07/07/url-retrieve-and-json-api/#comment-175 353 | - http://nullprogram.com/blog/2014/05/27/ 354 | - http://nullprogram.com/blog/2016/06/16/ 355 | - http://debbugs.gnu.org/cgi/bugreport.cgi?bug=20159 356 | - https://gist.github.com/arnested/3006911 357 | 358 | * The extra headers :headers:req:url:http: 359 | 360 | - ~url-request-method~ 361 | - ~url-request-extra-headers~ 362 | - ~url-request-data~ 363 | 364 | * Requests: emacswiki examples POST :example:req:url:http: 365 | 366 | #+NAME: emacswiki-url-post 367 | #+BEGIN_SRC elisp 368 | (defun my-url-http-post (url args) 369 | 370 | "Send ARGS to URL as a POST request." 371 | (let ((url-request-method "POST") 372 | (url-request-extra-headers 373 | '(("Content-Type" . "application/x-www-form-urlencoded"))) 374 | (url-request-data 375 | (mapconcat (lambda (arg) 376 | (concat (url-hexify-string (car arg)) 377 | "=" 378 | (url-hexify-string (cdr arg)))) 379 | args 380 | "&"))) 381 | ;; if you want, replace `my-switch-to-url-buffer' with `my-kill-url-buffer' 382 | (url-retrieve url 'my-switch-to-url-buffer))) 383 | 384 | (defun my-kill-url-buffer (status) 385 | "Kill the buffer returned by `url-retrieve'." 386 | (kill-buffer (current-buffer))) 387 | 388 | (defun my-switch-to-url-buffer (status) 389 | "Switch to the buffer returned by `url-retreive'. 390 | The buffer contains the raw HTTP response sent by the server." 391 | (switch-to-buffer (current-buffer))) 392 | 393 | ;; And then you can do the following: 394 | 395 | ;; (my-url-http-post "http://localhost/test.cgi" '(("post" . "1") ("text" . "just a test"))) 396 | #+END_SRC 397 | 398 | * Requests: emacswiki examples GET :example:req:url:http: 399 | 400 | #+NAME: emacswiki-url-get 401 | #+BEGIN_SRC elisp 402 | (defvar fb-url "https://www.googleapis.com/freebase/v1/search") 403 | 404 | (defun fbquery (type str) 405 | (let ((url-request-method "GET") 406 | (arg-stuff (concat "?query=" (url-hexify-string str) 407 | "&filter=" (url-hexify-string type)))) 408 | (url-retrieve (concat fb-url arg-stuff) 409 | (lambda (status) (switch-to-buffer (current-buffer)))))) 410 | #+END_SRC 411 | * Requests: emacswiki examples cookies :example:req:url:http: 412 | 413 | #+NAME: emacswiki-url-cookies 414 | #+BEGIN_SRC elisp 415 | ;; To reject all cookies (see also ‘url-privacy-level’): 416 | 417 | (setq url-cookie-untrusted-urls '(".*")) 418 | 419 | ;; Say you want to ignore all cookies except those set by the 420 | ;; EmacsWiki site. Using ".*" for ‘url-cookie-untrusted-urls’ in this 421 | ;; case will always result in the cookie being rejected, because it 422 | ;; matches the whole string. Try the following regular expression 423 | ;; instead: 424 | 425 | (setq url-cookie-trusted-urls '("^http://\\(www\\.\\)?emacswiki\\.org/.*") 426 | url-cookie-untrusted-urls '("^https?://")) 427 | 428 | ;; Each cookie is a defstruct, and all cookies are stored in a list 429 | ;; defined by ‘url-cookie-storage’ and persistently in the file 430 | ;; ‘url-cookie-file’. Cookies are automatically saved to this file 431 | ;; once every ‘url-cookie-save-interval’ seconds. 432 | #+END_SRC 433 | 434 | * Requests: rosettacode example :example:req:url:http: 435 | #+NAME: rosettacode-emacslisp-url-get 436 | #+BEGIN_SRC elisp 437 | (with-current-buffer 438 | (url-retrieve-synchronously "http://www.rosettacode.org") 439 | (goto-char (point-min)) 440 | (search-forward "\n\n" nil t) ;; skip headers 441 | (prin1 (buffer-substring (point) (point-max))) 442 | (kill-buffer (current-buffer))) 443 | #+END_SRC 444 | 445 | * Requests: frozenlock example :example:req:url:http: 446 | 447 | #+NAME: frozenlock-get-parse-json-leaky 448 | #+BEGIN_SRC elisp 449 | ;; Original 450 | ;; - https://frozenlock.org/tag/url-retrieve/ 451 | 452 | ;; Now as long as we remain in this let function, we can get the 453 | ;; google buffer with the symbol buffer. Let’s skip some steps and go 454 | ;; to the interesting part: 455 | 456 | (defun get-json (url) 457 | (let ((buffer (url-retrieve-synchronously url)) 458 | (json nil)) 459 | (save-excursion 460 | (set-buffer buffer) 461 | (goto-char (point-min)) 462 | (re-search-forward "^$" nil 'move) 463 | (setq json (buffer-substring-no-properties (point) (point-max))) 464 | (kill-buffer (current-buffer))) 465 | json)) 466 | 467 | ;; This function will return any content from a given url. 468 | 469 | ;; Ok, we have the JSON formatted data, what can we do with it? Of 470 | ;; course, Emacs already has a JSON parser. Simply make sure you 471 | ;; require ‘json before going any further. 472 | 473 | (defun get-and-parse-json (url) 474 | (let ((json-object-type 'plist)) 475 | (json-read-from-string 476 | (get-json url)))) 477 | 478 | ;; Here I’ve choosen to parse it as a PLIST, be it could as well be an 479 | ;; ALIST, or even an hash-table! 480 | 481 | ;; improved 482 | ;; - https://frozenlock.org/2012/07/07/url-retrieve-and-json-api/#comment-175 483 | 484 | (defun get-and-parse-json (url) 485 | (interactive) 486 | (with-current-buffer (url-retrieve-synchronously url) 487 | (goto-char (point-min)) 488 | (re-search-forward “^$”) 489 | (json-read))) 490 | #+END_SRC 491 | 492 | * Uh-oh :req:url:http: 493 | 494 | *DANGER* all of the above examples may leak buffers, per 495 | http://nullprogram.com/blog/2014/05/27/ 496 | 497 | #+NAME: nullprogram-leaky 498 | #+BEGIN_SRC elisp 499 | ;; Ultimately this makes buffer objects poor return values. It’s an 500 | ;; impedance mismatch. The caller has to be careful to free (“kill”) 501 | ;; the buffer. It’s easy to miss if an error is signaled. For example, 502 | ;; `url-retrieve' and `url-retrieve-synchronously' return a buffer 503 | ;; with the response from a web server. It’s not uncommon for Elisp 504 | ;; programs to leak these buffers during normal operation. 505 | 506 | (with-current-buffer (url-retrieve-synchronously some-url) 507 | (setf (point) url-http-end-of-headers) 508 | (prog1 (json-read) 509 | (kill-buffer))) 510 | 511 | ;; If json-read fails, the buffer is leaked. 512 | #+END_SRC 513 | 514 | * Safer :req:url:http: 515 | 516 | #+NAME: nullprogram-buffer-passing 517 | #+HEADER: :var some-url="" 518 | #+BEGIN_SRC elisp 519 | (with-temp-buffer 520 | (url-retrieve-synchronously some-url) 521 | (setf (point) url-http-end-of-headers) 522 | (json-read)) 523 | #+END_SRC 524 | 525 | * Uh-oh :req:url:http: 526 | :PROPERTIES: 527 | :header-args: :results value raw 528 | :END: 529 | 530 | #+CALL: nullprogram-buffer-passing("https://api.github.com/users/octocat/orgs") 531 | 532 | : executing Elisp code block (nullprogram-buffer-passing)... 533 | 534 | : (some-url (quote "https://api.github.com/users/octocat/orgs")) 535 | 536 | : Contacting host: api.github.com:443 537 | : setf: Symbol's value as variable is void: url-http-end-of-headers 538 | 539 | * WTF :req:url:http: 540 | 541 | - https://fossies.org/diffs/emacs/24.3_vs_24.4/lisp/url/url-http.el-diff.html 542 | 543 | * End of part n :plan: 544 | 545 | Next time: 546 | 547 | - processing responses 548 | - mocking and stubbing 549 | - packaging 550 | 551 | * References :about: 552 | 553 | ** TDD 554 | 555 | - http://martinfowler.com/bliki/TestDrivenDevelopment.html 556 | - http://www.jamesshore.com/Agile-Book/test_driven_development.html 557 | - http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html 558 | 559 | ** ERT 560 | 561 | - http://nullprogram.com/blog/2012/08/15/ 562 | 563 | ** Making HTTP requests with the ~url~ package 564 | 565 | - https://www.emacswiki.org/emacs/UrlPackage 566 | - https://www.rosettacode.org/wiki/HTTP#Emacs_Lisp 567 | - http://emacs.stackexchange.com/questions/12464/go-to-body-after-url-retrieve-synchronously 568 | - https://frozenlock.org/tag/url-retrieve/ 569 | - https://frozenlock.org/2012/07/07/url-retrieve-and-json-api/#comment-175 570 | - http://nullprogram.com/blog/2014/05/27/ 571 | - http://nullprogram.com/blog/2016/06/16/ 572 | - http://debbugs.gnu.org/cgi/bugreport.cgi?bug=20159 573 | - https://gist.github.com/arnested/3006911 574 | 575 | ** Getting the response body 576 | 577 | - http://emacs.stackexchange.com/questions/12464/go-to-body-after-url-retrieve-synchronously 578 | 579 | * COMMENT org settings 580 | #+LANGUAGE: en 581 | #+SELECT_TAGS: export 582 | #+EXCLUDE_TAGS: noexport 583 | #+CREATOR: Emacs 24.5.1 (Org mode 8.3.4) 584 | #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline 585 | #+OPTIONS: author:t c:nil creator:nil d:(not "LOGBOOK") date:t e:t 586 | #+OPTIONS: email:nil f:t inline:t num:t p:nil pri:nil prop:nil stat:t 587 | #+OPTIONS: tags:t tasks:t tex:t timestamp:t title:t toc:t todo:t |:t 588 | -------------------------------------------------------------------------------- /workshops/keyboard-macros.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Workshop for Emacs Macros 2 | #+AUTHOR: Howard Abrams 3 | #+DATE: 2015 Nov 24 4 | #+TAGS: emacs workshop 5 | #+STARTUP: hideblocks 6 | 7 | Basic idea of this file is to be both a *guide* and a *practice pad* 8 | for leveling up on Emacs’ keyboard macro system. 9 | 10 | To use, just [[https://github.com/howardabrams/pdx-emacs-hackers/raw/master/workshops/keyboard-macros.org][download this file]] to your system, and edit it in Emacs. 11 | Then just follow along... If you are not familiar with org-mode files, 12 | here are the basics for this workshop: 13 | 14 | - Hit a tab on the header expands or collapses it 15 | - Narrow to show just one section with: C-x n s 16 | - Return by widening normally with: C-x n w 17 | - Hyperlinks can be clicked on to view the Emacs Manual 18 | 19 | Pretty much treat the rest of this document as a text file. 20 | 21 | * Basic Usage 22 | 23 | Let’s begin with something simple to try out this project. 24 | In the /block area/ below, hit: C-c ' (yes, the apostrophe). 25 | When done with the tasks, hit: C-x C-s to close and return here. 26 | 27 | #+BEGIN_SRC org 28 | - this should be interesting 29 | - nulla posuere 30 | - nullam tempus 31 | - etiam laoreet quam sed arcu 32 | - donec hendrerit tempor tellus 33 | - mauris mollis tincidunt felis 34 | - etiam laoreet quam sed arcu 35 | - nullam rutrum 36 | - sed diam 37 | - lorem ipsum dolor sit amet, consectetuer adipiscing elit 38 | - mauris ac felis vel velit tristique imperdiet 39 | - fusce suscipit, wisi nec facilisis facilisis, est dui fermentum leo, quis tempor ligula erat quis odio 40 | - donec hendrerit tempor tellus 41 | #+END_SRC 42 | 43 | Notice that the frame is split with this document still visible? 44 | 45 | Good, let’s play around. Let’s capitalize the first letter of each line. 46 | Position point at the beginning of the first line, and then: 47 | 48 | - F3 49 | - M-c 50 | - C-n 51 | - C-a 52 | - F4 53 | 54 | Press F4 repeatedly to capitalize the first word on each line. 55 | Don’t capitalize /every/ line... leave a few alone for a moment. 56 | Now you have the basics. 57 | 58 | Let’s make a new macro to capitalize the /last/ word on each line. 59 | Pop back up to the top of the list, and: 60 | 61 | - F3 62 | - C-e 63 | - M-b 64 | - M-c 65 | - C-n 66 | - F4 67 | 68 | Once again, leave a few lines alone. 69 | Just one more macro, as I want to show you something interesting. 70 | Jump back to the beginning, and: 71 | 72 | - F3 73 | - C-a 74 | - M-f 75 | - Space 76 | - foobar (or type any single word you find amusing) 77 | - C-n 78 | - F4 79 | 80 | Type: C-x C-k C-k 81 | 82 | Notice it behaves the same as F4, but you can keep typing C-k to 83 | execute your macro. 84 | 85 | Start typing C-n and/or C-p and notice the minibuffer. It alternates 86 | between the following: 87 | 88 | - M-c C-n C-a 89 | - C-e M-b M-c C-n 90 | - C-a M-f SPC f 2*o b a r C-n 91 | 92 | Typing C-k at any point will execute that macro. You’ve now see the 93 | Emacs Macro Ring, and can manipulate it. You are now at Level 2. 94 | 95 | Type C-c ' (apostrophe) to close that side window. 96 | 97 | * Naming Macros 98 | 99 | While that =foobar= macro may be quite handy, looping around the 100 | keyboard macro ring to select it may be inefficient. Name it! 101 | 102 | C-x C-k n 103 | 104 | Give it a name of foobar, and now, you can: M-x foobar 105 | to have the macro run. 106 | 107 | Perhaps it may be more useful to bind that macro to some un-used 108 | key, like C-c k or F2 ... type: 109 | 110 | C-x C-k b 111 | 112 | And then type your binding, e.g. C-c k 113 | 114 | You know that C-c followed by a single letter is supposed to be free 115 | of usage and available for your nefarious reasons, right? 116 | 117 | Read the [[info:emacs#Save%20Keyboard%20Macro][the Emacs Manual]] for details. If you actually tried this 118 | example, then you have earned enough experience points to be level 3. 119 | 120 | * What do you mean On Every Line? 121 | 122 | Keyboard macros are slick, and while we /could/ prefix the F4 with 123 | the numbering prefix to run it multiple times at once, e.g. C-9 F4, 124 | a typical use case is to run it on every line in a region. 125 | 126 | Position the cursor in the block, and type: C-c ‘ 127 | 128 | #+BEGIN_SRC org 129 | I will take out the trash 130 | I should stop swearing 131 | I may stop to smell the roses 132 | I do want to go shopping 133 | I could care less 134 | #+END_SRC 135 | 136 | With the point on the first line, type: 137 | 138 | - F3 139 | - C-a 140 | - M-f 141 | - M-f 142 | - Space 143 | - not (type the word, =not=) 144 | - F4 145 | 146 | Now select the remaining 4 lines any way you like, and type: 147 | 148 | - C-x C-k r 149 | 150 | Read [[info:emacs#Basic%20Keyboard%20Macro][the Emacs Manual]] for complete details, and welcome to level 4. 151 | 152 | * Numbering 153 | 154 | Numbering things seems to be important to people. Let’s see if we 155 | can easily number the worst song ever inflicted on humanity. 156 | 157 | Once again, position the point inside the block, and type: C-c ' 158 | 159 | #+BEGIN_SRC org 160 | Drummers Drumming 161 | Pipers Piping 162 | Lords a Leaping 163 | Ladies Dancing 164 | Maids a Milking 165 | Swans a Swimming 166 | Geese a Laying 167 | Golden Rings 168 | Calling Birds 169 | French Hens 170 | Turtle Doves 171 | Partridge in a Pear Tree 172 | #+END_SRC 173 | 174 | Follow along at home. First, position the point at the end (on the 175 | line with the partridge), and: 176 | 177 | - C-x C-k C-c 178 | - 1 179 | - Return (to set a counter to 1) 180 | - F3 181 | - C-a 182 | - F3 183 | - Spacebar 184 | - C-n 185 | - F4 186 | 187 | Yes, hitting the F3 key twice (once to start the macro, and again to 188 | insert the value of the counter) is a bit odd. You can also use the 189 | binding: C-x C-k C-i 190 | 191 | Each time you hit F4, you increment the counter that is inserted. 192 | 193 | By the way, if you didn’t do the whole =C-x C-k C-c= to set the 194 | counter to 1, the first value would be 0. Read [[info:emacs#Keyboard%20Macro%20Counter][the manual]] for 195 | details. 196 | 197 | * Fixing Macros 198 | 199 | Now that you are a Level 5 Elf Keyboard Macro-er, and you can now 200 | sling macros everywhere, you may notice that sometimes, in the 201 | middle of a long macro, you flub it. 202 | 203 | If you hit F4 too soon (it happens), hit: C-u C-u F3 to pick up 204 | where you left off and enter the rest of the macro. Hit F4 when you 205 | are really finished. 206 | 207 | If you need to fix a keyboard macro with more finesse, type: 208 | 209 | C-x C-k C-e 210 | 211 | And behold the glory. Tis a simple language that should be pretty 212 | obvious to a skilled Macro-er as yourself. Type C-h m once in that 213 | buffer to display details of how to edit the macro. When you are 214 | finished editing, type: C-c C-c 215 | 216 | I’ll let you play around with your own example for this one. 217 | Read [[info:emacs#Edit%20Keyboard%20Macro][the manual]] for complete details. 218 | 219 | * Variations on a Theme 220 | 221 | To gain the Level 7 Keyboard Macro-er title, one should know how to 222 | customize a macro /while/ running it. The following section of HTML 223 | code needs some textual changes. We want to add one of the following 224 | phrases to the /end/ of every paragraph that has a =class= of =change=: 225 | 226 | * Because I said so. Got it? 227 | * Because I'm the boss. Got it? 228 | * You heard me. Got it? 229 | * Just do it. Got it? 230 | 231 | To begin, first move to the following block (hint: C-c M-f) and hit 232 | TAB to collapse the block (you gotta see all the instructions, 233 | right?) Next, issue a C-c ' on this block to show it in a new 234 | window. If you have trouble with your HTML mode, change the =html= 235 | to =text=. 236 | 237 | #+BEGIN_SRC html 238 | 239 | 240 | 241 |

242 | Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus. 243 | Praesent augue. Sed diam. Nunc eleifend leo vitae magna. Nunc 244 | rutrum turpis sed pede. 245 |

246 |

247 | Nullam rutrum. Nunc rutrum turpis sed pede. 248 |

249 |

250 | Phasellus at dui in ligula mollis ultricies. Curabitur lacinia 251 | pulvinar nibh. Donec pretium posuere tellus. Praesent 252 | fermentum tempor tellus. Proin quam nisl, tincidunt et, mattis 253 | eget, convallis nec, purus. 254 |

255 |

256 | Fusce sagittis, libero non molestie mollis, magna orci ultrices 257 | dolor, at vulputate neque nulla lacinia eros. Sed diam. Nam 258 | vestibulum accumsan nisl. 259 |

260 |

261 | Aliquam feugiat tellus ut neque. Nam vestibulum accumsan 262 | nisl. Praesent fermentum tempor tellus. 263 |

264 |

265 | Vivamus id enim. Suspendisse potenti. Curabitur lacinia 266 | pulvinar nibh. Mauris ac felis vel velit tristique imperdiet. 267 |

268 |

269 | Donec vitae dolor. Mauris ac felis vel velit tristique 270 | imperdiet. Nunc aliquet, augue nec adipiscing interdum, lacus 271 | tellus malesuada massa, quis varius mi purus non odio. Proin 272 | quam nisl, tincidunt et, mattis eget, convallis nec, purus. Nam 273 | euismod tellus id erat. 274 |

275 |

276 | Nullam rutrum. 277 |

278 | 279 | 280 | #+END_SRC 281 | 282 | Type the following: 283 | 284 | - F3 285 | - C-s 286 | - Type: class="change" 287 | - C-e 288 | - C-s 289 | - Type:

290 | - C-p 291 | - C-e 292 | - C-x q 293 | - Type: Got it? 294 | - C-n 295 | - F4 296 | 297 | In this particular case, we actually didn't do anything special, so 298 | move to the beginning of the buffer, and hit F4, and the cursor will 299 | go to the end of every paragraph that needs changing, and stop with 300 | a prompt: 301 | 302 | Proceed with macro? (Y, N, RET, C-l, C-r) 303 | 304 | Type C-r and begin typing one of our phrases, and when you are done, 305 | type: C-M-c 306 | 307 | The prompt will be re-displayed, so finish the macro with 'Y'. 308 | Check out [[info:emacs#Keyboard%20Macro%20Query][the manual]] for details on this =C-x q= business. 309 | -------------------------------------------------------------------------------- /workshops/org-mode-beginner.org: -------------------------------------------------------------------------------- 1 | #+HTML_HEAD: 2 | *IMPORTANT*: Use C-n, C-p to navigate around and follow the *directions*. 3 | 4 | *directions*: Move the cursor to the beginning of the line that says "Fast 5 | Intro" and hit the TAB button 1 time! 6 | 7 | * Fast Intro 8 | *Welcome* to the Org mode Beginner's Workshop! You just learned how to move 9 | around and /cycle/ through an org-mode outline. Cycling is what happens when TAB 10 | is pressed on a *heading*. A heading is denoted by one or more astericks. The 11 | asterick count represents the level of nesting for the heading. 12 | 13 | *directions*: Cycle through the following headings. You will see "..." when a 14 | heading has more information. 15 | 16 | ** Org-mode background 17 | - [[Carsten Dominik][Carsten Dominik]] is the creator of org-mode. 18 | - He is an astronomer and has to manage lots of notes and todos. When he 19 | starts a project he begins with notes and then develops tasks. There were 20 | just no good tools for combining note taking and todo management and so 21 | org-mode was born. 22 | - Started in 2003, open source project that is distributed with emacs 24 and on. 23 | - Why work with text files 24 | - portlable formats (read/edit anywhere) 25 | - grep and other UNIX tools 26 | - Process with perl,python,etc 27 | - Problem-free history with version control 28 | - Synchronize org files with git 29 | ** Start your engines 30 | - Make sure your version of emacs is up to date (at least 24) otherwise YMMV 31 | - If it isn't working then try adding the following to your init.el 32 | 33 | #+BEGIN_SRC emacs-lisp 34 | ;;;;org-mode configuration 35 | ;; Enable org-mode 36 | ;(require 'org) 37 | ;; Make org-mode work with files ending in .org 38 | ;(add-to-list 'auto-mode-alist '("\\.org$" . org-mode)) 39 | ;; The above is the default in recent emacsen 40 | #+END_SRC 41 | 42 | 1. Move cursor inside of the "#+BEGIN_SRC org" and "#+END_SRC" lines. 43 | 2. Type C-c ' 44 | 3. The example will appear within a new buffer 45 | 4. Type C-c ' 46 | 5. The example will close. Try it below: 47 | 48 | #+BEGIN_SRC org 49 | ,* This is not a test 50 | #+END_SRC 51 | 52 | - Great! Now continue learning about Outline mode by following [[Introducing Outline mode][this link]]. click it, place 53 | the cursor on the link and type C-c C-o, or use the function 54 | /org-open-at-point/. 55 | 56 | * Introducing Outline mode 57 | - Org-mode is fantastic at managing ordered and unordered lists, hyperlinking 58 | documents, embedding source code, and so much more. Outline mode is the way to 59 | get around in an org file. 60 | 61 | *directions*: Run the example below (hint: hit C-c ' inside code blocks) then observe the behavior of 62 | the TAB key and S-TAB key. 63 | 64 | #+BEGIN_SRC org 65 | ,* Heading 66 | ,** Subheading 67 | - Here is some information 68 | ,*** Subheading 69 | - Here is some more information 70 | ,* Heading 2 71 | ,** Subheading 2.1 72 | ,* Settings 73 | ,** Another setting 74 | ,*** More settings 75 | 76 | #+END_SRC 77 | 78 | - What does TAB do? 79 | When point is at the beginning of a headline, rotate the subtree started by this 80 | line through 3 different states (local cycling): 81 | 1. FOLDED: Only the main headline is shown. 82 | 2. CHILDREN: The main headline and the direct children are shown. From this state, you can move to one of the children and zoom in further. 83 | 3. SUBTREE: Show the entire subtree, including body text. 84 | If there is no subtree, switch directly from CHILDREN to FOLDED. 85 | 86 | - What does S-TAB do? 87 | Global visibility cycling 88 | 1. OVERVIEW 89 | 2. CONTENTS 90 | 3. SHOW ALL 91 | 92 | *** Navigating the outline mode 93 | 94 | - The main keys you will use to move around are: 95 | #+BEGIN_EXAMPLE 96 | C-c C-n - move point up one heading 97 | C-c C-p - move point down one heading 98 | C-c C-b - move point up one heading on same level 99 | C-c C-f - move point down one heading on same level 100 | 101 | TAB - cycle local visibility 102 | S-TAB - cycle globabl visibilty 103 | 104 | M-UP - move heading up one 105 | M-DOWN - move heading down one 106 | M-RIGHT - increase heading indentation 107 | M-LEFT - decrease heading indentation 108 | #+END_EXAMPLE 109 | 110 | - Experiment with the previous keybindings in the following example: 111 | #+BEGIN_SRC org 112 | ,* Book Outline - Business Secrets of the Pharaohs 113 | ,** Chapter 3 - Egypt and Wall Street 114 | ,*** Yadda yadda yadaa 115 | ,**** Phasellus neque orci, porta a, aliquet quis, semper a, massa. 116 | ,**** Nullam tristique diam non turpis. 117 | ,**** Aliquam posuere. 118 | ,**** Nunc rutrum turpis sed pede. 119 | ,*** Blah Blah Blah 120 | ,**** Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 121 | ,***** vivamus id enim. 122 | ,****** Nullam rutrum. 123 | ,** Chapter 2 - Ancient Economics 124 | ,*** Curabitur lacinia pulvinar nibh. 125 | ,**** Mauris mollis tincidunt felis. 126 | ,*** Nullam eu ante vel est convallis dignissim. 127 | ,**** Nulla facilisis, risus a rhoncus fermentum, tellus tellus lacinia purus, et dictum nunc justo sit amet elit. 128 | ,**** Aenean in sem ac leo mollis blandit. 129 | ,***** Nunc rutrum turpis sed pede. 130 | ,** Chapter 4 - Title pending 131 | ,*** Aliquam erat volutpat. 132 | ,**** Nullam libero mauris, consequat quis, varius et, dictum id, arcu. 133 | ,**** Nam euismod tellus id erat. 134 | ,**** Nam euismod tellus id erat. 135 | ,** Chapter 1 - Correlations or Lack Thereof 136 | ,*** Cras placerat accumsan nulla. 137 | ,*** Donec hendrerit tempor tellus. 138 | ,**** Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. 139 | ,* References 140 | ,** Referemce 1 141 | *** more information 142 | 143 | #+END_SRC 144 | 145 | - If you have made it this far, you now have what it takes navigate around an 146 | org document. But what fun is that? Click [[Simple todo list][this link]] to see how to create a 147 | simple todo list. 148 | * Simple todo list 149 | - This simple todo list features the same old headings we are used you. In 150 | addition to the heading we now have *TODO* and *DONE* *states* associated with the 151 | heading. 152 | #+BEGIN_EXAMPLE 153 | C-c Return - Insert a new todo item 154 | S-Right - Toggle through item states 155 | S-Left - Toggle through item states 156 | C-c t - Toggle the state of a todo item 157 | #+END_EXAMPLE 158 | 159 | *directions*: use the keybindings above to experiment with the following example: 160 | 161 | #+BEGIN_SRC org 162 | ,* Stuff I must do 163 | ,** Run a 5k 164 | ,** Return package to seller 165 | ,** TODO Invoice project X for 1 billion dollars 166 | ,** TODO Read latest documentation on technology Y 167 | ,** TODO Practice guitar for 1 hour 168 | ,** TODO Debug gaming pc's videocard 169 | ,** TODO Backup the backup of the backup 170 | ,** TODO Buy flowers 171 | ,** TODO Take out the compost 172 | ,** DONE Think about emacs 173 | #+END_SRC 174 | 175 | - Next, learn about *checkboxes* by creating [[A%20Grocery%20List][a grocery list]]. 176 | * A Grocery List 177 | - In this example, we are keeping track of what foods we like and we can see at 178 | a glance which items should be stocked. 179 | 180 | #+BEGIN_EXAMPLE 181 | C-c C-c - toggle checkbox marked 182 | C-c - - turn headline into a plain list entry 183 | C-c * - turn a plain list entry into a headline 184 | C-c Return - create a new plain list entry above or below line; dependent on cursor position (start or end of line) 185 | [/] - type at end of heading to display a checklist counter 186 | #+END_EXAMPLE 187 | 188 | *directions*: Experiment with the keybindings above to create new entries and 189 | toggle checkboxes. 190 | 191 | #+BEGIN_SRC org 192 | ,* A Grocery list 193 | ,*note*: [X] denotes stocked 194 | [ ] denotes not stocked 195 | ,** Meats [4/9] 196 | - [ ] Chicken breast 197 | - [ ] Salmon cutlets 198 | - [X] Tuna 199 | - [X] Sardines 200 | - [ ] Steak 201 | - [ ] Bacon 202 | - [X] Eggs 203 | - [X] Beef Kielbasa 204 | - [ ] Pork shoulder 205 | ,** Dairy [3/5] 206 | - [X] Whole Milk 207 | - [X] Cottage Cheese 208 | - [X] Muenster Cheese 209 | - [ ] Greek Yoghurt 210 | - [ ] Butter 211 | ,** Veggies [1/6] 212 | - [ ] Carrots 213 | - [ ] Broccoli 214 | - [X] Spinash 215 | - [ ] Celery 216 | - [ ] Cauliflower 217 | - [ ] Avocado 218 | ,** Other [2/7] 219 | - [ ] Bananas 220 | - [X] Bread 221 | - [ ] Pasta 222 | - [ ] Green Tea 223 | - [X] Earl Grey Tea 224 | - [ ] Sparkling Water 225 | - [ ] Olive Oil 226 | 227 | #+END_SRC 228 | 229 | - Hey, nice progress! Next on the agenda is to learn about *tags* and *properties*. We will 230 | utilize everything we know so far to make [[A reading list][a reading list]]. 231 | 232 | * A reading list 233 | - Everybody should have a reading list. You can track across categories like 234 | reading, read, and to-read. But you can also track the page you are on and 235 | take notes right in org-mode. 236 | - *tags* come at the end of a heading and look like this ":foo:" and ":foo:bar:" 237 | - *properties* are key-value pairs of data associated with a heading. 238 | - the properties are in a "drawer" which stays closed while cycling. 239 | - open the :properties: drawer by placing curson on it and TAB. 240 | 241 | #+BEGIN_EXAMPLE 242 | C-c C-z - Add a note to a heading 243 | C-c C-c (on heading) - Add a tag to a heading 244 | C-c C-c (on checkbox) - Toggle checkbox checked 245 | C-c C-c (on :PROPERTIES:) - Manage properties 246 | C-c C-x p - Set property 247 | #+END_EXAMPLE 248 | 249 | *directions*: Experiment with the commands you know and the new commands with 250 | the following example: 251 | 252 | #+BEGIN_SRC org 253 | ,* TODO My Reading List 254 | ,** currently 255 | 256 | ,*** TODO structure interpretation of computer programs :compsci:lisp: 257 | :PROPERTIES: 258 | :PAGECOUNT: 350 259 | :CURRENTPAGE: 100 260 | :AUTHOR: Harold Abelson,Gerald Jay Sussman,Julie Sussman 261 | :PUBLISHER: MIT Press 262 | :END: 263 | - Note taken on [2016-01-19 Tue 02:33] \\ 264 | read for 1 hour. page 45 265 | ,**** Chapters Outline [1/4] 266 | - [X] Chapter 1 267 | - [-] Chapter 2 [1/3] 268 | - [-] Sec 1 269 | - [ ] Sec 1a 270 | - [X] Sec 1b 271 | - [X] Sec 1c 272 | - [X] Sec 1d 273 | - [X] Sec 2 274 | - [X] Sec 1a 275 | - [ ] Sec 3 276 | - [-] Chapter 3 [2/4] 277 | - [X] Sec 1a 278 | - [X] Sec 1b 279 | - [ ] Sec 1c 280 | - [ ] Sec 1d 281 | - [-] Chapter 4 [2/4] 282 | - [ ] Sec 1a 283 | - [X] Sec 1b 284 | - [ ] Sec 1c 285 | - [X] Sec 1d 286 | 287 | ,**** Chapter Notes 288 | ,***** Chapter 1 :economics: 289 | - Nam vestibulum accumsan nisl. 290 | - In id erat non orci commodo lobortis. 291 | - Etiam vel neque nec dui dignissim bibendum. 292 | - Nam vestibulum accumsan nisl. 293 | - Vestibulum convallis, lorem a tempus semper, dui dui euismod elit, vitae 294 | placerat urna tortor vitae lacus. 295 | - Donec neque quam, dignissim in, mollis nec, sagittis eu, wisi. Nullam 296 | tristique diam non turpis. 297 | ,***** Chapter 2 :world:impact: 298 | 1. Nullam rutrum. 299 | 2. Mauris ac felis vel velit tristique imperdiet. 300 | 3. Phasellus purus. Aliquam erat volutpat. Aliquam posuere. Aliquam erat volutpat. 301 | 4. Phasellus at dui in ligula mollis ultricies. Nunc porta vulputate tellus. Nullam tempus. 302 | 1. Nulla facilisis, risus a rhoncus fermentum, tellus tellus lacinia purus, et dictum nunc justo sit amet elit. 303 | 2. Phasellus at dui in ligula mollis ultricies. 304 | 3. Aliquam erat volutpat. 305 | 5. Phasellus purus. Nam euismod tellus id erat. Pellentesque tristique imperdiet tortor. Nullam tempus. 306 | ,***** Chapter 3 :digitalcurrency: 307 | ,****** Something else 308 | 1. Nam a sapien. Phasellus at dui in ligula mollis ultricies. Praesent augue. 309 | 2. Praesent augue. Curabitur vulputate vestibulum lorem. Aliquam feugiat tellus ut neque. 310 | ,***** Chapter 4 :economics: 311 | - Phasellus at dui in ligula mollis ultricies.Phasellus at dui in ligula mollis 312 | ultricies. 313 | - Cum sociis natoque penatibus et magnis dis parturient montes, nascetur 314 | ridiculus mus. 315 | ,** Finished 316 | ,*** TODO Some new book 317 | ,*** DONE Book X :comedy:nonfiction: 318 | ,*** DONE Book Y :drama:fiction: 319 | ,*** DONE Book Z :history: 320 | ,** Queue 321 | ,*** Book A :comedy:fiction: 322 | ,*** Book B :nonfiction:history: 323 | ,*** Book C :programming: 324 | ,*** Book D :lisp:emacs: 325 | 326 | #+END_SRC 327 | 328 | Go on and learn more about [[A%20Linking%20Tutorial][linking]] in org-mode. 329 | * A Linking Tutorial 330 | - It can be really useful to link directly to other documents, emails, and web 331 | pages right there in your notes. 332 | 333 | #+BEGIN_EXAMPLE 334 | C-c C-l - Insert a link 335 | C-c l - Store a link to the current location 336 | C-c C-o - Open link 337 | C-u C-c C-l - Insert a link to a file 338 | C-c C-x C-n - Visit next link 339 | C-c C-x C-p - Visit previous link 340 | C-c % - Push the current position onto the mark ring 341 | C-c & - Jump back to a recorded position. 342 | [[url][desc]] - Literally typing in a link 343 | #+END_EXAMPLE 344 | 345 | - Use the keybindings above to experiment with the following cs50 syllabus list: 346 | 347 | #+BEGIN_SRC org 348 | ,* Resources 349 | - [[https://courses.edx.org/courses/HarvardX/CS50x3/2015/courseware/43d165ac1d974f20a55585da76d39277/010c11db84a647e39a42cd191035b499/][CS50 Main Page EDX]] 350 | - [[https://courses.edx.org/courses/HarvardX/CS50x3/2015/info][Course Information]] 351 | - [[https://youtu.be/vpy_C36d_Eg][Intro Video]] 352 | - [[https://courses.edx.org/courses/HarvardX/CS50x3/2015/a7ec0c0a7b6e460f877da0734811c4cd/][Discussion]] 353 | - [[https://www.reddit.com/r/cs50]] 354 | ,* Week 0 355 | ,** Lectures [2/2] 356 | - [X] [[https://youtu.be/zFenJJtAEzE][Lecture]] 357 | - [X] [[https://youtu.be/UuFWYOnHwGM][Lecture Continued]] 358 | ,** Walkthroughs [9/15] 359 | - [X] [[https://youtu.be/tveoFN0NHE0][Hello Scratch]] 360 | - [X] [[https://youtu.be/kjqREWts-WU][Meow]] 361 | - [X] [[https://youtu.be/92ALk-oEjis][Meow Resources]] 362 | - [X] [[https://youtu.be/OGY8lbrvN_Y][Meow Meow Meow]] 363 | - [X] [[https://youtu.be/jneprjYU-wM][Pet The Cat]] 364 | - [X] [[https://youtu.be/982SmMd0wgI][Don't Pet The Cat]] 365 | - [X] [[https://youtu.be/U7z503AVryY][Hi Hi Hi]] 366 | - [ ] [[https://youtu.be/9s3cZ3DBUwE][Counting Sheep]] 367 | - [ ] [[https://youtu.be/2_7oC9QW3j8][Cough-0]] 368 | - [ ] [[https://youtu.be/gb341GXeskk][Cough-1]] 369 | - [ ] [[https://youtu.be/u-vSE5alMdw][Cough-2]] 370 | - [ ] [[https://youtu.be/HchQ1p-is5A][Cough-3]] 371 | - [ ] [[https://youtu.be/1yG1uUH-sCw][Cough-4]] 372 | - [X] [[https://youtu.be/G3z6aIwi_JA][Threads]] 373 | - [X] [[https://youtu.be/bgfiyeEDz-U][Events]] 374 | 375 | ,** Shorts [5/5] 376 | - [X] [[https://youtu.be/HFLczUUHWNw][Algorithms]] 377 | - [X] [[https://youtu.be/UPlR4eMMCmI][ASCII Resources]] 378 | - [X] [[https://youtu.be/hacBFrgtQjQ][Binary Resources]] 379 | - [X] [[https://youtu.be/52JoFF4HMA4][Scratch Resources]] 380 | - [X] [[https://youtu.be/3YD66bHehhQ][Threads Resources]] 381 | 382 | ,** Problem Set 0: Scratch 383 | - To submit this problem set, visit http://cs50.edx.org/2016/psets/0/. You’ll 384 | find that a few questions await. Be extra-sure that your answers are 385 | correct, particularly your project’s URL on MIT’s website, lest we overlook 386 | your submission! 387 | - [ ] http://cdn.cs50.net/2016/x/psets/0/pset0/pset0.html 388 | ,* Week 1 389 | ,* Week 2 390 | ,* Week 3 391 | * Week 4 392 | #+END_SRC 393 | * Your Personal Wiki 394 | ** About Section 395 | Hey, I'm /me/. I *love* [[Movies][Movies]], [[Music][Music]], and [[Writing][Writing]]. 396 | ** Movies 397 | *** The Big Lebowski 398 | *** Vanilla Sky 399 | *** The Matrix 400 | *** The Royal Tenenbaums 401 | *** Documentaries 402 | **** [[https://youtu.be/EfDEM1C7ad8?list%3DPL6WB-A3vU_274McvXu_yel-qa5O-TG0mx][Britannia History]] 403 | **** [[https://www.youtube.com/watch?v%3DnjwQgz63rIs][The Grand Narrative of the History of Computing]] 404 | ** Music 405 | - Pink Floyd 406 | - James Taylor 407 | - Red House Painters 408 | ** Writing 409 | *** Working title 410 | Nullam *tristique* diam non */turpis/*. =Curabitur vulputate vestibulum lorem.= 411 | ~inlined code~ tristique imperdiet tortor. Lorem ipsum dolor sit amet, 412 | =verbatim text= consectetuer adipiscing elit. Phasellus purus. _Aliquam posuere._ Cras 413 | +deleted text+ placerat accumsan nulla. Nam a sapien. Nam vestibulum accumsan nisl. 414 | Aliquam with sub_{script} such as H_{2}0. 415 | *** Another 416 | Etiam vel neque nec dui dignissim bibendum. Fusce sagittis, libero non 417 | molestie mollis, magna orci ultrices dolor, at vulputate neque nulla lacinia 418 | eros. Donec at pede. Nunc eleifend leo vitae magna. Donec hendrerit 419 | tempor tellus. Donec at pede. Donec at pede. Nullam rutrum. Nullam 420 | tristique diam non turpis. Sed id ligula quis est convallis tempor. Nullam 421 | tristique diam non turpis. Nullam tristique diam non turpis. Donec neque 422 | quam, dignissim in, mollis nec, sagittis eu, wisi. Phasellus neque orci, 423 | porta a, aliquet quis, semper a, massa. Phasellus neque orci, porta a, 424 | aliquet quis, semper a, massa. Etiam laoreet quam sed arcu. Sed diam. 425 | Suspendisse potenti. Phasellus purus. Vestibulum convallis, lorem a tempus 426 | semper, dui dui euismod elit, vitae placerat urna tortor vitae lacus. 427 | Phasellus lacus. Etiam vel tortor sodales tellus ultricies commodo. Nullam 428 | tristique diam non turpis. Mauris ac felis vel velit tristique imperdiet. 429 | Curabitur lacinia pulvinar nibh. Nunc rutrum turpis sed pede. Etiam vel 430 | neque nec dui dignissim bibendum. Aliquam posuere. Fusce sagittis, libero 431 | non molestie mollis, magna orci ultrices dolor, at vulputate neque nulla 432 | lacinia eros. Cras placerat accumsan nulla. 433 | * Resources 434 | - https://github.com/fniessen/refcard-org-mode 435 | - [[https://github.com/rayners/emacs.d/blob/master/rayners/org.el]] 436 | - [[http://orgmode.org/orgcard.txt][http://orgmode.org/orgcard.txt]] 437 | - http://orgmode.org/manual/Setting-tags.html 438 | - http://www.deepakg.com/prog/2011/11/emacs-org-mode-todo-list-nirvana/ 439 | - [[http://doc.norang.ca/org-mode.html]] 440 | -------------------------------------------------------------------------------- /workshops/org-mode-gtd-feature-demo.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 2016-02-17 Org-mode GTD 2 | #+DATE: <2016-02-07 Sun> 3 | #+AUTHOR: William Clifford 4 | #+EMAIL: wobh@yahoo.com 5 | #+AUTHOR: Lake Denman 6 | #+EMAIL: 7 | 8 | * Introduction 9 | 10 | Topic for today is org agenda views, scheduling tasks, archiving and 11 | refiling, and time tracking. 12 | 13 | * Demo Setup 14 | 15 | ** Properties 16 | 17 | #+PROPERTY: Effort_ALL 1 2 3 5 8 13 18 | #+TODO: TODO DOING | DONE 19 | 20 | ** Keys 21 | 22 | We will regularly visit the agenda and timeline throughout this 23 | workshop. Below are three commands recommended for Org-mode 24 | setup. The one for =org-agenda= is critical. 25 | 26 | #+HEADER: :results value 27 | #+BEGIN_SRC elisp 28 | (global-set-key "\C-cl" 'org-store-link) 29 | (global-set-key "\C-cb" 'org-iswitchb) 30 | (global-set-key "\C-ca" 'org-agenda) 31 | #+END_SRC 32 | 33 | #+RESULTS: 34 | : org-agenda 35 | 36 | ** Commands 37 | 38 | - C-c [ :: add current file to agenda files list 39 | - C-c ] :: remove current file from agenda files list 40 | 41 | ** Steps 42 | 43 | 1. =emacs -q org-mode-datetimes.org= 44 | 2. ~C-c [~ 45 | 46 | * A few words about Properties and Columns 47 | 48 | We have to mention properties because almost everything about setting 49 | and using datetimes intersects with the Org-mode feature of "Properties". 50 | 51 | Properties provide a way for org to keep track of "metadata" about the 52 | entries in the outline. They're simple key-value pairs that may appear 53 | under the headline in a special properties block like so: 54 | 55 | ** Example headline with property drawer :example: 56 | :PROPERTIES: 57 | :example-property-key: example value 58 | :another-property-key: another value 59 | :END: 60 | 61 | In this example we see two properties of this headline. They were set 62 | with the =org-set-property= (~C-c C-x p~) command. The ~:PROPERTIES:~ 63 | and ~:END:~ delimiters around them mark the beginning and ending of a 64 | "drawer" which allow you to hide or reveal them ~TAB~ as you would 65 | other headlines, but they are automatically expanded with the 66 | headline. 67 | 68 | Related topics to explore another time include: 69 | 70 | - Customized and other drawer types (although we'll see one specialty 71 | drawer, ~:LOGBOOK:~) 72 | - You can display them in Org column view (we'll be introduced to 73 | agenda view later this session) 74 | - Properties inheritance by child headlines, 75 | - Searching Properties 76 | - Properies can be setup with auto-complete and cycling values 77 | 78 | We're not going to talk about this much more, except to say that /all/ 79 | the metadata about an Org-mode headline is considered a property. The 80 | features you know already, TODO state, tags, priority, are properties 81 | with special syntax. There's other special syntax properties and we're 82 | going to discuss them right away. 83 | 84 | ** Column view quick intro 85 | 86 | Quick intro here, circle back regularly. 87 | 88 | - C-c C-x C-c :: Column view 89 | - q :: exit column view 90 | - g :: refresh column view 91 | - C-l :: recenter-top-bottom, *very* handy for bringing a headline in 92 | column view up to the headers. 93 | 94 | ** [0/4] columns task list :example: 95 | :PROPERTIES: 96 | :COLUMNS: %40ITEM %17Effort{+} %PRIORITY %TODO %CLOCKSUM 97 | :END: 98 | 99 | *** TODO [#A] task 1 100 | :PROPERTIES: 101 | :Effort: 2 102 | :END: 103 | 104 | *** TODO [#B] task 2 105 | :PROPERTIES: 106 | :Effort: 3 107 | :END: 108 | 109 | *** TODO [#C] task 3 110 | :PROPERTIES: 111 | :Effort: 5 112 | :END: 113 | 114 | *** TODO task 4 115 | :PROPERTIES: 116 | :Effort: 8 117 | :END: 118 | 119 | * Timestamps 120 | 121 | ** Datetime Formats 122 | 123 | There's two kinds of timestamp 124 | 125 | - <2016-02-17 Wed> :: an "active" timestamp ~C-c .~ 126 | - [2016-02-17 Wed] :: an "inactive" timestamp ~C-c !~ 127 | 128 | Active timestamps are included in the Agenda. To include a time in the 129 | timestamp use the argument ~C-u C-c .~ or ~C-u C-c !~ 130 | 131 | - <2016-02-17 Wed 18:45> 132 | - [2016-02-17 Wed 18:30] 133 | 134 | * Deadlines and Schedules 135 | 136 | - C-c C-d :: insert deadline 137 | - C-c C-s :: insert schedule 138 | - C-c C-t :: increment TODO state 139 | 140 | examples below: 141 | 142 | ** DONE meet with Will to work on PDX-Emacs presentation :example: 143 | SCHEDULED: <2016-02-13 Sat 20:30> 144 | 145 | ** DONE write date time and agenda presentations :example: 146 | DEADLINE: <2016-02-16 Tue> 147 | 148 | ** Biweekly unrequired thing :example: 149 | SCHEDULED: <2016-02-26 Fri +2w> 150 | 151 | ** PDX-Emacs meetup as diary floating date :example: 152 | <%%(diary-float t 3 3)> 18:30 153 | 154 | ** TODO Monthly Scheduled Todo Thingy :example: 155 | SCHEDULED: <2016-04-13 Wed ++1m> 156 | :PROPERTIES: 157 | :END: 158 | - State "DONE" from "TODO" [2016-02-13 Sat 22:40] 159 | - State "DONE" from "TODO" [2016-02-13 Sat 22:35] 160 | :PROPERTIES: 161 | :LAST_REPEAT: [2016-02-13 Sat 22:40] 162 | :END: 163 | 164 | #+BEGIN_QUOTE 165 | Marking this DONE will shift the date by at least one week, 166 | but also by as many weeks as it takes to get this date into 167 | the future. However, it stays on a Sunday, even if you called 168 | and marked it done on Saturday. 169 | #+END_QUOTE 170 | 171 | ** TODO repeated entry every some odd days :example: 172 | SCHEDULED: <2017-04-03 Mon +2d> 173 | :PROPERTIES: 174 | :LAST_REPEAT: [2016-02-17 Wed 19:13] 175 | :END: 176 | - State "DONE" from "TODO" [2016-02-17 Wed 19:13] 177 | #+BEGIN_QUOTE 178 | Marking this DONE will shift the date to one month after 179 | today. 180 | #+END_QUOTE 181 | 182 | ** Valentines Day :example: 183 | SCHEDULED: <2016-02-14 Sun ++y> 184 | 185 | * Time Clock 186 | 187 | Time clocks are useful for tracking time spent on tasks. 188 | 189 | - C-c C-x C-i :: Clock into a task 190 | - C-c C-x C-o :: Clock out of a task 191 | - C-c C-x C-j :: Move point to current running clock 192 | - C-c C-x C-q :: Cancel the current clock. This is useful if a 193 | clock was started by mistake, or if you ended up 194 | working on something else. 195 | - C-c C-x C-j :: Jump to the headline of the currently clocked in 196 | task. With a ~C-u~ prefix arg, select the target 197 | task from a list of recently clocked tasks. 198 | - C-c C-x C-d :: Display time summaries for each subtree in the 199 | current buffer. Press ~C-c C-c~ or start typing to 200 | remove. 201 | 202 | - C-c C-c :: Recalculate the resulting time 203 | - C-c C-t :: Changing the TODO state of an item to DONE 204 | automatically stops the clock if it is running in this 205 | same item. 206 | 207 | ** Writing Time Clock :example: 208 | CLOCK: [2016-02-15 Mon 22:18]--[2016-02-16 Tue 22:30] => 24:12 209 | 210 | ** TODO Todo item :example: 211 | :LOGBOOK: 212 | CLOCK: [2016-02-17 Wed 19:19]--[2016-02-17 Wed 19:19] => 0:00 213 | CLOCK: [2016-02-17 Wed 19:17]--[2016-02-17 Wed 19:19] => 0:02 214 | CLOCK: [2016-02-15 Mon 22:48]--[2016-02-15 Mon 22:50] => 0:02 215 | :END: 216 | 217 | ** Clocking in multiple times :example: 218 | CLOCK: [2016-02-15 Mon 22:35]--[2016-02-15 Mon 22:38] => 0:03 219 | CLOCK: [2016-02-15 Mon 22:30]--[2016-02-15 Mon 22:35] => 0:05 220 | CLOCK: [2016-02-15 Mon 22:20]--[2016-02-15 Mon 22:25] => 0:05 221 | 222 | ** Clock table :example: 223 | CLOCK: [2016-02-15 Mon 22:35]--[2016-02-15 Mon 22:38] => 0:03 224 | CLOCK: [2016-02-15 Mon 22:30]--[2016-02-15 Mon 22:35] => 0:05 225 | CLOCK: [2016-02-15 Mon 20:20]--[2016-02-15 Mon 22:25] => 2:05 226 | #+BEGIN: clocktable :maxlevel 2 :scope subtree 227 | #+CAPTION: Clock summary at [2016-02-17 Wed 19:24] 228 | | Headline | Time | | 229 | |-------------------------+--------+------| 230 | | *Total time* | *2:13* | | 231 | |-------------------------+--------+------| 232 | | \_ Example clock table | | 2:13 | 233 | #+END: 234 | 235 | - C-c C-x C-r :: insert clock table (careful not to run twice) 236 | - C-c C-x C-u :: update clock table 237 | 238 | * Effort estimates 239 | 240 | - C-c C-x e :: set effort property 241 | 242 | ** File settings for efforts 243 | 244 | In lengths of time: 245 | 246 | : #+PROPERTY: Effort_ALL 1:00 2:00 3:00 5:00 8:00 13:00 247 | 248 | In agile points, Fibonacci distribution: 249 | 250 | : #+PROPERTY: Effort_ALL 1 2 3 5 8 13 251 | 252 | ** Project :example: 253 | :PROPERTIES: 254 | :Effort: 3 255 | :COLUMNS: %40ITEM(Task) %17Effort(Estimated Effort){+} %CLOCKSUM 256 | :END: 257 | :LOGBOOK: 258 | CLOCK: [2016-02-17 Wed 15:26]--[2016-02-17 Wed 19:26] => 4:00 259 | :END: 260 | 261 | *** Subproject :example: 262 | :PROPERTIES: 263 | :Effort: 3 264 | :END: 265 | :LOGBOOK: 266 | CLOCK: [2016-02-17 Wed 13:30]--[2016-02-17 Wed 16:30] => 3:00 267 | CLOCK: [2016-02-16 Tue 16:30]--[2016-02-16 Tue 18:30] => 2:00 268 | :END: 269 | 270 | * Agenda and timeline views 271 | 272 | - C-ca :: agenda menu 273 | - a :: agenda for week or day 274 | - f :: forward 275 | - b :: backward 276 | - d :: day view 277 | - w :: week view 278 | - y :: year view 279 | - L :: go to location and recenter 280 | - C-c C-x b :: go to location in indirect buffer 281 | - L :: timeline 282 | - l :: log mode toggle - shows clocks for day 283 | 284 | * Archive/Refile 285 | 286 | - C-c C-w :: refile entry or region to another headline or file 287 | 288 | ** Awesome stuff I'm going to do :example: 289 | *** TODO stuff 290 | *** DONE things 291 | 292 | ** Awesome stuff I did :example: 293 | 294 | * Putting it all together: sprint plan 295 | 296 | - [[file:org-mode-gtd-sprint-demo.org]] 297 | 298 | * References 299 | ** Properties 300 | - [[info:org#Properties and columns]] 301 | - [[info:org#Property syntax]] 302 | - [[info:org#Special%20properties][info:org#Special properties]] 303 | - [[info:org#Column%20view][info:org#Column view]] 304 | ** Timestamps 305 | - [[info:org#Timestamps]] 306 | ** Schedules and Deadlines 307 | 308 | 309 | - [[info:org#Inserting deadline/schedule]] 310 | 311 | 312 | asdlfhasdlkfjlkjasldkjfasdlkfjlkjf 313 | 314 | sdfgskjdfg;lkdj 315 | 316 | ** Agenda 317 | - 318 | 319 | * COMMENT org settings 320 | #+LANGUAGE: en 321 | #+SELECT_TAGS: export 322 | #+EXCLUDE_TAGS: noexport 323 | #+CREATOR: Emacs 24.5.1 (Org mode 8.3.3) 324 | #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline 325 | #+OPTIONS: author:t c:nil creator:nil d:(not "LOGBOOK") date:t e:t 326 | #+OPTIONS: email:nil f:t inline:t num:t p:nil pri:nil prop:nil stat:t 327 | #+OPTIONS: tags:t tasks:t tex:t timestamp:t title:t toc:t todo:t |:t 328 | #+STARTUP: hidestars 329 | -------------------------------------------------------------------------------- /workshops/org-mode-gtd-feature-demo.org_archive: -------------------------------------------------------------------------------- 1 | # -*- mode: org -*- 2 | 3 | 4 | Archived entries from file ./workshops/org-mode-gtd-feature-demo.org 5 | 6 | 7 | * DONE This is done 8 | SCHEDULED: <2016-02-15 Mon> 9 | :PROPERTIES: 10 | :ARCHIVE_TIME: 2016-02-17 Wed 19:47 11 | :ARCHIVE_FILE: ./workshops/org-mode-gtd-feature-demo.org 12 | :ARCHIVE_OLPATH: Archive/refile 13 | :ARCHIVE_CATEGORY: org-mode-datetimes 14 | :ARCHIVE_TODO: DONE 15 | :END: 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /workshops/org-mode-gtd-sprint-demo.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Emacs Org-mode GTD sprint demo 2 | #+DATE: <2016-02-13 Sat> 3 | #+AUTHOR: William Clifford 4 | #+EMAIL: wobh@yahoo.com 5 | #+PROPERTY: Effort_ALL 1 2 3 4 5 8 6 | #+TODO: TODO DOING WAIT | DONE NOPE 7 | #+TODO: GOTO HERE | WENT SKIP 8 | 9 | 10 | * Introduction 11 | 12 | A simple org file showing a fake sprint. 13 | 14 | ** Setup 15 | 16 | Custom TODO settings I like to have: 17 | 18 | For Features and Tasks 19 | 20 | - TODO 21 | - WAIT 22 | - DOING 23 | - DONE 24 | - NOPE 25 | 26 | For meetings: 27 | 28 | - GOTO 29 | - HERE 30 | - WENT 31 | - SKIP 32 | 33 | * Backlog 34 | ** Epic 1 35 | *** Description 36 | So epic. 37 | *** Story 1 38 | **** Description 39 | *** Story 2 40 | **** Description 41 | 42 | * Current sprint 43 | :PROPERTIES: 44 | :COLUMNS: %45ITEM %PRI %Effort{+} %TODO %TAGS %CLOCKSUM 45 | :END: 46 | - C-c C-x i :: org-insert-columns-dblock 47 | 48 | #+BEGIN: columnview :hlines 1 :id local 49 | | ITEM | PRI | Effort | TODO | TAGS | CLOCKSUM | 50 | |-------------------+-----+--------+------+--------+----------| 51 | | * Current sprint | | 15 | | | 0:02 | 52 | | ** Meetings [2/2] | | | | :meet: | | 53 | | *** Planning | | | WENT | | | 54 | | *** Retro | | | SKIP | | | 55 | | ** Bug 1 | | | DONE | | | 56 | | ** Task 1 | | 2 | DONE | | | 57 | | ** Feature 1 | | 1 | NOPE | | 0:02 | 58 | | ** Task 2 | | 4 | NOPE | | | 59 | | ** Feature 2 | | 2 | NOPE | | | 60 | | ** Task 3 | | 2 | TODO | | | 61 | | ** Task 4 | | 2 | TODO | | | 62 | | ** Bug 2 | | 2 | TODO | | | 63 | #+END: 64 | 65 | ** Meetings [2/2] :meet: 66 | *** WENT Planning 67 | SCHEDULED: <2016-02-15 Mon 09:00-12:00> 68 | *** SKIP Retro 69 | SCHEDULED: <2016-02-26 Fri 16:00-17:00> 70 | ** DONE Bug 1 71 | DEADLINE: <2016-02-16 Tue> 72 | 73 | ** DONE Task 1 74 | DEADLINE: <2016-02-17 Wed> 75 | :PROPERTIES: 76 | :epic: [[*Epic 1]] 77 | :story: [[*Story 1]] 78 | :Effort: 2 79 | :END: 80 | 81 | ** NOPE Feature 1 82 | DEADLINE: <2016-02-18 Thu> 83 | :PROPERTIES: 84 | :epic: [[*Epic 1]] 85 | :story: [[*Story 1]] 86 | :Effort: 1 87 | :END: 88 | :LOGBOOK: 89 | CLOCK: [2016-02-17 Wed 19:56]--[2016-02-17 Wed 19:56] => 0:00 90 | CLOCK: [2016-02-17 Wed 19:52]--[2016-02-17 Wed 19:54] => 0:02 91 | :END: 92 | ** NOPE Task 2 93 | DEADLINE: <2016-02-19 Fri> 94 | :PROPERTIES: 95 | :epic: [[*Epic 1]] 96 | :story: [[*Story 1]] 97 | :Effort: 4 98 | :END: 99 | 100 | ** NOPE Feature 2 101 | DEADLINE: <2016-02-22 Mon> 102 | :PROPERTIES: 103 | :epic: [[*Epic 1]] 104 | :story: [[*Story 2]] 105 | :Effort: 2 106 | :END: 107 | 108 | ** TODO Task 3 109 | DEADLINE: <2016-02-23 Tue> 110 | :PROPERTIES: 111 | :epic: [[*Epic 1]] 112 | :story: [[*Story 1]] 113 | :Effort: 2 114 | :END: 115 | 116 | ** TODO Task 4 117 | DEADLINE: <2016-02-24 Wed> 118 | :PROPERTIES: 119 | :epic: [[*Epic 1]] 120 | :story: [[*Story 2]] 121 | :Effort: 2 122 | :END: 123 | 124 | ** TODO Bug 2 125 | DEADLINE: <2016-02-25 Thu> 126 | :PROPERTIES: 127 | :Effort: 2 128 | :END: 129 | 130 | * COMMENT org settings 131 | #+LANGUAGE: en 132 | #+SELECT_TAGS: export 133 | #+EXCLUDE_TAGS: noexport 134 | #+CREATOR: Emacs 24.5.1 (Org mode 8.3.3) 135 | #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline 136 | #+OPTIONS: author:t c:nil creator:nil d:(not "LOGBOOK") date:t e:t 137 | #+OPTIONS: email:nil f:t inline:t num:t p:nil pri:nil prop:nil stat:t 138 | #+OPTIONS: tags:t tasks:t tex:t timestamp:t title:t toc:t todo:t |:t 139 | #+STARTUP: hidestars 140 | -------------------------------------------------------------------------------- /workshops/org-mode-intro/for-the-host.el: -------------------------------------------------------------------------------- 1 | ;;; FOR-THE-HOST --- Code for the host of the workshop, not attendees 2 | ;; 3 | ;; Author: Howard Abrams 4 | ;; Copyright © 2015, Howard Abrams, all rights reserved 5 | ;; Created: 2015 Dec 19 6 | ;; 7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 8 | ;; 9 | ;;; Commentary: 10 | ;; 11 | ;; This is code to simply set up the host of this workshop with an 12 | ;; environment that maximizes the screen estate so that everyone 13 | ;; can see the most amount of information projected. 14 | ;; 15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 16 | ;; 17 | ;;; Change log: 18 | ;; 19 | ;; 20 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21 | ;; 22 | ;; This program is free software; you can redistribute it and/or 23 | ;; modify it under the terms of the GNU General Public License as 24 | ;; published by the Free Software Foundation; either version 3, or 25 | ;; (at your option) any later version. 26 | ;; 27 | ;; This program is distributed in the hope that it will be useful, 28 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ;; General Public License for more details. 31 | ;; 32 | ;; You should have received a copy of the GNU General Public License 33 | ;; along with this program; see the file COPYING. If not, write to 34 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth 35 | ;; Floor, Boston, MA 02110-1301, USA. 36 | ;; 37 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 38 | ;; 39 | ;;; Code: 40 | 41 | ;; Got the packages? 42 | (when (not (require 'use-package nil t)) 43 | (package-install 'use-package)) 44 | 45 | (use-package demo-it 46 | :ensure t) 47 | 48 | (use-package org-tree-slide 49 | :ensure t 50 | :config 51 | (org-tree-slide-simple-profile)) 52 | 53 | ;; ---------------------------------------------------------------------- 54 | ;; Create each function that represents a "presentation frame" 55 | 56 | (defun org-mode-intro-load-presentation () 57 | "Display for-the-host.org (an 'org-mode' file) as a presentation." 58 | ;; After the demonstration, we'll restore the original state 59 | (demo-it-frame-fullscreen) 60 | (delete-other-windows) 61 | (demo-it-presentation "instructions.org") 62 | (demo-it-load-file "sandbox.org" 'side 2)) 63 | 64 | (defun org-mode-intro-load-part-2 () 65 | "Load a pre-written org file with predefined sections." 66 | (interactive) 67 | ;; If we switch to the original sandbox file, we can replace that 68 | ;; buffer window with a new one. 69 | (pop-to-buffer "sandbox.org") 70 | (demo-it-load-file "sandbox-2.org" nil 2)) 71 | 72 | ;; ---------------------------------------------------------------------- 73 | ;; Demonstration and/or Presentation Order 74 | 75 | (defun org-mode-intro-start-presentation () 76 | "Start hosting mode for this workshop. 77 | 78 | Rebind F12 to advance the presentation, while C-F12 will load the 79 | next file to edit." 80 | (interactive) 81 | 82 | (define-key demo-it-mode-adv-map (kbd "C-") 'demo-it-step) 83 | (define-key demo-it-mode-adv-map (kbd "") 'demo-it-presentation-advance) 84 | 85 | (demo-it-start (list 'org-mode-intro-load-presentation 86 | 'org-mode-intro-load-part-2) t)) 87 | 88 | ;; ---------------------------------------------------------------------- 89 | ;; Start the presentation whenever this script is evaluated. Good idea? 90 | 91 | (org-mode-intro-start-presentation) 92 | 93 | (provide 'org-mode-intro) 94 | 95 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 96 | ;;; for-the-host.el ends here 97 | -------------------------------------------------------------------------------- /workshops/org-mode-intro/instructions.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Introduction to Org Mode 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2015 Dec 19 5 | #+TAGS: emacs presentation org-mode 6 | 7 | * Structural Basics 8 | 9 | Time to learn ORG MODE!! 10 | 11 | We'll begin this session by creating an org-mode file with a number 12 | of /sections/ and learn how to move and manipulate them. 13 | 14 | Our goal for this is to show how org-mode files are better than 15 | Markdown, and just as easy to use. 16 | 17 | #+BEGIN_QUOTE 18 | If you are the host or running this as in the presentation mode, 19 | advance these instructions with =F12= ... 20 | #+END_QUOTE 21 | 22 | ** Creating Sections 23 | 24 | Create a file called: =sandbox.org= 25 | 26 | Enter a lot of headers and sub-headers: 27 | - Top-level headers have a single asterisk at start of line 28 | - Sub-level headers have more than one asterisk 29 | 30 | #+BEGIN_SRC org 31 | * Top Header One 32 | ** Sub header A 33 | ** Sub header B 34 | ** Sub header C 35 | * Top Header Two 36 | ** Nudder Nested Header 37 | #+END_SRC 38 | 39 | Type some words and whatnot under the headers to 40 | create /sections/. 41 | 42 | ** Easier Headers 43 | 44 | Instead of typing the astericks, this is Emacs, and 45 | we have key-bindings for easily creating org-mode 46 | formatting code. 47 | 48 | - =C-RET= :: to create a header section of the same level 49 | - =M-= :: increases sub-header 50 | - =M-= :: decreases sub-header 51 | 52 | While you /can/ simply add/remove asterisks, the Meta arrow 53 | key-binding also increases the indention of the text in that 54 | section. 55 | 56 | ** Moving Between Sections 57 | 58 | While all of the standard Emacs movement keybindings work, try: 59 | 60 | - =C-c C-n= :: To move to the next section header (or =C-M-n=) 61 | - =C-c C-p= :: To move to the previous section header (=C-M-p=) 62 | - =C-c C-f= :: To move to header at the same level (on 63 | top-level? go to the next top-level) 64 | - =C-c C-b= :: To move to previous header at same level 65 | - =C-c C-^= :: To move to the parent header (yeah, odd binding) 66 | 67 | Good features to focus on a section: 68 | 69 | - =C-x n s= :: To narrow to the org-mode section 70 | - =C-x n w= :: To widen back to the full text 71 | 72 | ** Collapsing Sections 73 | 74 | Now that you have the basics of org-mode sections, add some text to 75 | one or two sections. 76 | 77 | Move the section header (=C-c C-p=) and hit =TAB= 78 | 79 | Hit it again. Notice that section of text is hidden and then shown. 80 | 81 | Hit: =Shift-TAB= ... Do that multiple times to show and hide all 82 | the sections. 83 | 84 | When Org loads a new file all the top-level sections have been 85 | collapsed to show the structure. 86 | 87 | ** Section Summary 88 | 89 | You should now be able to: 90 | 91 | - Create sections and sub-sections by defining headers 92 | - Quickly move between the sections 93 | - Use various way to focus on a section 94 | 95 | 96 | * Text and Paragraphs 97 | 98 | In this part, we'll play around with regular text entry 99 | with the =sandbox-2.org= file, which you can download at: 100 | 101 | http://is.gd/org_sandbox 102 | 103 | Or: git clone https://github.com/howardabrams/pdx-emacs-hackers) 104 | 105 | Or: Type really fast as we show off more features. 106 | 107 | #+BEGIN_QUOTE 108 | Note: If you are hosting this demonstration, 109 | hit =C-F12= to load the file. 110 | #+END_QUOTE 111 | 112 | ** Paragraphs 113 | 114 | Move to the first section (*Paragraphs*), and type: =C-x n s= 115 | 116 | org-mode works well with [[info:emacs#Visual%20Line%20Mode][Visual Line Mode]], or 117 | with [[info:emacs#Fill%20Commands][Fill Commands]]. 118 | 119 | Many like to indent the text to align with the 120 | header level. Try indenting and filling this text. 121 | 122 | If you have an [[http://www.emacswiki.org/emacs/UnfillParagraph][Unfill Paragraph]] function, try converting 123 | it to a single line with =visual-line-mode= on (to 124 | create a single line, use: =C-x f 999 RET M-q=. 125 | 126 | ** Bold, Italics and Whatnot 127 | 128 | Like Wikis and Markdown, org-mode has its formatting 129 | abilities. Surround text with the following 130 | characters: 131 | 132 | - Bold :: Surrounded with *asterisks*: * 133 | - Italics :: Surrounded with /slashes/: / 134 | - Underline :: Surrounded with _under-bars_: _ 135 | - Fixed-width :: Surrounded with =equal signs=: = 136 | - Code :: Surrounded with ~tilde characters~: ~ 137 | - Strike-Through :: Surround with +striked+ : + 138 | 139 | Check out [[https://github.com/howardabrams/dot-files/blob/master/emacs.org#user-content-block-wrappers][insert-pair or wrap-region]] to make this easier. 140 | 141 | Oh, and the formatting characters can be hidden to make your Emacs 142 | look like a word processor. 143 | 144 | #+BEGIN_SRC elisp 145 | (setq org-hide-emphasis-markers t) 146 | #+END_SRC 147 | 148 | ** Links 149 | 150 | Links make =org-mode= better than Markdown in Emacs. 151 | 152 | Copy or type the following into your file: 153 | 154 | #+BEGIN_SRC org 155 | This links to [[http://www.google.com][Google]]. 156 | #+END_SRC 157 | 158 | Clicking a link opens the default browser. 159 | 160 | Make another link by highlighting some words, and typing: =C-c C-l= 161 | Links can refer to files: 162 | 163 | #+BEGIN_SRC org 164 | Like your [[file:~/.emacs][[Emacs Configuration]] file. 165 | #+END_SRC 166 | 167 | Or to internal headers in the same file: 168 | 169 | #+BEGIN_SRC org 170 | Like this: [[*Links][Links]] 171 | #+END_SRC 172 | 173 | Or even to the [[info:org#Hyperlink][internal Emacs documentation]], or (with Tramp) 174 | reference files on remote machines. 175 | 176 | ** Lists 177 | 178 | Widen the section (=C-x n w=), and open the next section, *Some 179 | Lists*. 180 | 181 | Lists are like headers, but with initial whitespace. We often use 182 | dashes instead of astericks, but they work the same way. 183 | 184 | Make a list or, if using the sandbox file, position point at the 185 | end (where it says =sed arcu=). (You can focus on this section 186 | with =C-x n s=) 187 | 188 | - Type =M-RET= to enter a new list element. 189 | 190 | - Type =M-= to move that element up the chain. 191 | 192 | - Type =M-= to make that element a sub-list. 193 | 194 | Like a header, =TAB= will collapse the subsections of a list. 195 | 196 | ** Ordered Lists 197 | 198 | In the next section, type a list that starts with a number. 199 | 200 | Type =M-RET= to enter a new item. Notice the same keys work for 201 | moving the list around, but the order stays the same. 202 | 203 | Try using the =Shift= key with the left and right arrow keys. 204 | Slick, huh? 205 | 206 | The following functions may be useful if bound since =C-= 207 | moves to the next list item and not to the end of the list. 208 | 209 | - =org-beginning-of-item-list= :: Jumps to the beginning of your list 210 | - =org-end-of-item-list= :: Jumps to the end of your list 211 | - =org-list-make-subtree= :: Converts a regular list into headers 212 | 213 | ** Tables 214 | 215 | A table is just data cells separated by vertical bars. 216 | Move to the /dash/ character in the *Tables* section: 217 | 218 | #+BEGIN_SRC org 219 | | Bottle | Distillery | Date | 220 | |- 221 | #+END_SRC 222 | 223 | Hit the tab key, and the rest of the cells will be formatted, 224 | and a header row inserted. 225 | 226 | Type information, and you'll notice the =|= character moving 227 | screwing up the alignment. No problem, just hit =TAB= again, and 228 | all is restored. 229 | 230 | Check out [[info:org#Built-in%20table%20editor][the documentation]] for simple tables. 231 | 232 | Tables are mini-spreadsheets and can automatically calculate 233 | columns and other calculations, but we are going to frustrate you 234 | by moving on to other features. 235 | 236 | ** Blocks 237 | 238 | Blocks are ways to organize paragraphs of text, for instance: 239 | 240 | #+BEGIN_SRC org 241 | , #+BEGIN_QUOTE 242 | To quote someone or something is divine. 243 | , #+END_QUOTE 244 | #+END_SRC 245 | 246 | (Blocks start with =#+= ... not with the comma you see above) 247 | 248 | #+BEGIN_SRC org 249 | , #+BEGIN_EXAMPLE 250 | Use to store log files or other data sections. 251 | , #+END_EXAMPLE 252 | #+END_SRC 253 | 254 | Especially source code (notice the language mode): 255 | 256 | #+BEGIN_SRC org 257 | , #+BEGIN_SRC ruby 258 | [1, 2, 3, 5, 7, 11, 13].each do |prime| 259 | puts prime 260 | end 261 | , #+END_SRC 262 | #+END_SRC 263 | 264 | Type C-c ' to edit the source code block in a Ruby buffer. 265 | (Note: First, execute =M-x load-library= and then =ob-ruby=) 266 | 267 | Type =C-x C-s= to return. Type =C-c C-c= to execute it. 268 | We'll have a full workshop on this /literate programming/. 269 | See the [[info:org#Working%20with%20source%20code][Info pages]] for details. 270 | 271 | * Exporting 272 | 273 | Org mode files can be exported to a variety of formats. 274 | 275 | Type =C-c C-e= and a Helm-like buffer will appear for all the 276 | formats you have loaded. 277 | 278 | Don't have enough? =M-x load-libary= the following: 279 | 280 | - =ox-html= :: Exports to HTML including direct loading into browser 281 | - =ox-freemind= :: Exports to a mind mapping software format 282 | - =ox-reveal= :: Exports as a presentation in a browser 283 | - =org-tree-slide= :: Displays org-mode as a Presentation in Emacs 284 | 285 | * Summary 286 | 287 | At this point, =org-mode= files should be better to you than normal 288 | Markdown files for general notes. 289 | 290 | However, we haven't scratched the surface. 291 | 292 | In the next workshop, we'll kick it up a notch, as we can use this to: 293 | 294 | - Organize ourselves 295 | - Literate programming 296 | - Exporting to web pages and presentations 297 | 298 | ** Org Capture 299 | 300 | Org comes with a Lisp macro allowing you to quickly add /sections/ 301 | to org-mode files without interrupting your current workflow. 302 | When you call =org-capture=, you may see something like: 303 | 304 | #+BEGIN_EXAMPLE 305 | Select a capture template 306 | ============================== 307 | 308 | [n] Thought or Note 309 | [j] Journal Note 310 | [t] Task Entry 311 | [e] Emacs Trick 312 | [c] Clojure Tip 313 | [b] Blog Entry 314 | [j] Journal Entry 315 | ----------------------------- 316 | [C] Customize org-capture-templates 317 | [q] Abort 318 | #+END_EXAMPLE 319 | 320 | What each entry does is customized with a somewhat 321 | [[info:org#Capture%20templates][involved Lisp macro]]. 322 | 323 | See [[https://github.com/howardabrams/dot-files/blob/master/emacs-org.org#auto-note-capturing][this example]] for ideas. 324 | -------------------------------------------------------------------------------- /workshops/org-mode-intro/sandbox-2.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Second Org Sandbox 2 | #+AUTHOR: (your name) 3 | #+EMAIL: (your email) 4 | #+DATE: 2016 Jan 20 5 | #+TAGS: orgmode 6 | 7 | * Paragraphs 8 | 9 | To help identify paragraphs and their sub-section, the left-side can 10 | be indented with spaces to line up with header. Both =TAB= and =M-q= 11 | works as *expected*. 12 | 13 | Play around with formatting this paragraph. 14 | Sed bibendum. Integer placerat tristique nisl. Etiam laoreet quam sed arcu. Vivamus id enim. 15 | Nunc porta vulputate tellus. 16 | Fusce commodo. 17 | Nullam rutrum. Phasellus at dui in ligula mollis ultricies. Mauris ac felis vel velit tristique imperdiet. 18 | 19 | * Some Lists 20 | 21 | - Nullam tempus 22 | - Donec vitae dolor 23 | - Donec pretium posuere tellus 24 | - Etiam laoreet quam sed arcu 25 | - Phasellus at dui in ligula mollis ultricies 26 | - Donec pretium posuere tellus 27 | - Pretium posuere tellus donec 28 | - Donec pretium posuere tellus 29 | - Nullam libero mauris, consequat quis, varius et, dictum id, arcu 30 | - Nullam tempus 31 | - Donec vitae dolor 32 | - Etiam laoreet quam sed arcu 33 | - Donec pretium posuere tellus 34 | - Etiam laoreet quam sed arcu 35 | - Phasellus at dui in ligula mollis ultricies 36 | - Nullam libero mauris, consequat quis, varius et, dictum id, arcu 37 | - Nullam tempus 38 | - Nullam tempus 39 | - Donec pretium posuere tellus 40 | - Etiam laoreet quam sed arcu 41 | 42 | ** Ordered Lists 43 | 44 | The stuff I need at the store are: 45 | 46 | 1. bread 47 | 2. cheese 48 | 3. milk 49 | 50 | ** Dictionary Lists 51 | 52 | These have the entry and its definition separated by two colons: 53 | 54 | - bear :: large, omnivorous animal that likes dancing in tutus 55 | - hippo :: large, hairless herbivore that looks better in tutus 56 | - ostrich :: flightless bird with bad temperament and nice sunglasses 57 | 58 | ** Mixed Lists 59 | 60 | My favorite scenes in the *Lord of the Rings* are: 61 | 62 | 1. The attack of the Rohirrim 63 | 2. Eowyn's fight with the witch king 64 | + this was already my favorite scene in the book 65 | + I really like Miranda Otto. 66 | 3. Peter Jackson being shot by Legolas 67 | - on DVD only 68 | - He makes a really funny face when it happens. 69 | 70 | * Tables 71 | 72 | Here is a table: 73 | 74 | | Bottle | Distillery | Date | 75 | |- 76 | 77 | * Blocks 78 | 79 | Here are some blocked structure to play with: 80 | 81 | #+BEGIN_QUOTE 82 | To quote someone or something is divine. 83 | #+END_QUOTE 84 | 85 | Type TAB on the "BEGIN" line to collapse it. 86 | 87 | #+BEGIN_EXAMPLE 88 | To quote someone or something is divine. 89 | #+END_EXAMPLE 90 | 91 | Especially source code (notice the language mode): 92 | 93 | #+BEGIN_SRC ruby 94 | [1, 2, 3, 5, 7, 11, 13].each do |prime| 95 | puts prime 96 | end 97 | #+END_SRC 98 | 99 | Type C-c and then ' to edit the source code block in a ruby buffer. 100 | Type C-x C-s to return. 101 | -------------------------------------------------------------------------------- /workshops/org-mode-intro/sandbox.org: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /workshops/org-mode-litp/agenda.org: -------------------------------------------------------------------------------- 1 | 2 | Hey! You made it to our new venue. 3 | 4 | - Wifi :: =foobar= 5 | - Pass :: =bartwo= 6 | 7 | * Agenda 8 | 9 | 10 | - Business Items 11 | - Need a new venue 12 | - Agenda for next month 13 | 14 | - Introductions 15 | - Primary use of Emacs 16 | - Use Emacs at your Day Job? 17 | - Your most novel, original, unique or strange hobby 18 | 19 | - Part 3 on org-mode Workshop: *Literate Programming* 20 | 21 | - Lightning Demonstrations 22 | 23 | - Office Hours 24 | -------------------------------------------------------------------------------- /workshops/org-mode-litp/for-the-host.el: -------------------------------------------------------------------------------- 1 | ;;; FOR-THE-HOST --- Code for the host of the workshop, not attendees 2 | ;; 3 | ;; Author: Howard Abrams 4 | ;; Copyright © 2016, Howard Abrams, all rights reserved 5 | ;; Created: 2016 Mar 16 6 | ;; 7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 8 | ;; 9 | ;;; Commentary: 10 | ;; 11 | ;; This is code to simply set up the host of this workshop with an 12 | ;; environment that maximizes the screen estate so that everyone 13 | ;; can see the most amount of information projected. 14 | ;; 15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 16 | ;; 17 | ;;; Change log: 18 | ;; 19 | ;; 20 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21 | ;; 22 | ;; This program is free software; you can redistribute it and/or 23 | ;; modify it under the terms of the GNU General Public License as 24 | ;; published by the Free Software Foundation; either version 3, or 25 | ;; (at your option) any later version. 26 | ;; 27 | ;; This program is distributed in the hope that it will be useful, 28 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | ;; General Public License for more details. 31 | ;; 32 | ;; You should have received a copy of the GNU General Public License 33 | ;; along with this program; see the file COPYING. If not, write to 34 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth 35 | ;; Floor, Boston, MA 02110-1301, USA. 36 | ;; 37 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 38 | ;; 39 | ;;; Code: 40 | 41 | ;; Got the packages? 42 | (when (not (require 'use-package nil t)) 43 | (package-install 'use-package)) 44 | 45 | (use-package demo-it 46 | :ensure t) 47 | 48 | (use-package org-tree-slide 49 | :ensure t 50 | :config 51 | (org-tree-slide-simple-profile)) 52 | 53 | ;; ---------------------------------------------------------------------- 54 | ;; Create each function that represents a "presentation frame" 55 | 56 | (defun org-mode-intro-pdx-emacs-display () 57 | "Display the PDX Emacs Hackers logo and agenda." 58 | (interactive) 59 | (let ((parent (file-name-directory (buffer-file-name)))) 60 | (demo-it-frame-fullscreen) 61 | (delete-other-windows) 62 | (find-file "../../support/pdx-emacs.png") 63 | (demo-it-hide-mode-line) 64 | (split-window) 65 | (other-window 1) 66 | (demo-it-presentation (concat parent "agenda.org") 2) 67 | (split-window-right) 68 | (other-window 1) 69 | (demo-it-presentation (concat parent "requirements.org") 2))) 70 | 71 | (defun org-mode-intro-load-presentation () 72 | "Display for-the-host.org (an 'org-mode' file) as a presentation." 73 | ;; After the demonstration, we'll restore the original state 74 | (delete-other-windows) 75 | (demo-it-presentation "instructions.org")) 76 | 77 | (defun org-mode-intro-load-part-2 () 78 | "Load a pre-written org file with predefined sections." 79 | (interactive) 80 | ;; If we switch to the original sandbox file, we can replace that 81 | ;; buffer window with a new one. 82 | ;; (pop-to-buffer "sandbox.org") 83 | (when (require 'mwe-log-commands nil t) 84 | (split-window-right) 85 | (add-to-list 'mwe:*log-command-exceptions* 'org-self-insert-command) 86 | (add-to-list 'mwe:*log-command-exceptions* 'org-delete-backward-char) 87 | (add-to-list 'mwe:*log-command-exceptions* 'company-ignore) 88 | (add-to-list 'mwe:*log-command-exceptions* 'ha/return-indent) 89 | (mwe:open-command-log-buffer t) 90 | (split-window-below) 91 | (enlarge-window 10)) 92 | (let ((parent (file-name-directory (buffer-file-name))) ) 93 | (demo-it-load-file (concat parent "sandbox.org") nil 2) 94 | (wrap-region-mode -1) 95 | (org-bullets-mode -1) 96 | (face-remap-add-relative 'org-level-4 '((:family "Source Code Pro" :height 148 :foreground "chocolate1"))) 97 | (face-remap-add-relative 'org-level-3 '((:family "Source Code Pro" :height 148 :foreground "Cyan1"))) 98 | (face-remap-add-relative 'org-level-2 '((:family "Source Code Pro" :height 148 :foreground "LightGoldenrod"))) 99 | (face-remap-add-relative 'org-level-1 '((:family "Source Code Pro" :height 148 :foreground "LightSkyBlue"))) 100 | (mwe:log-keyboard-commands) 101 | (delete-region (point-min) (point-max)))) 102 | 103 | ;; ---------------------------------------------------------------------- 104 | ;; Demonstration and/or Presentation Order 105 | 106 | (defun org-mode-intro-start-presentation () 107 | "Start hosting mode for this workshop. 108 | 109 | Rebind F12 to advance the presentation, while C-F12 will load the 110 | next file to edit." 111 | (interactive) 112 | 113 | (define-key demo-it-mode-adv-map (kbd "C-") 'demo-it-step) 114 | (define-key demo-it-mode-adv-map (kbd "") 'demo-it-presentation-advance) 115 | 116 | (demo-it-start (list 'org-mode-intro-pdx-emacs-display 117 | 'org-mode-intro-load-presentation 118 | 'org-mode-intro-load-part-2) t)) 119 | 120 | ;; ---------------------------------------------------------------------- 121 | ;; Start the presentation whenever this script is evaluated. Good idea? 122 | 123 | (org-mode-intro-start-presentation) 124 | 125 | (provide 'org-mode-intro) 126 | 127 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 128 | ;;; for-the-host.el ends here 129 | -------------------------------------------------------------------------------- /workshops/org-mode-litp/graphics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/workshops/org-mode-litp/graphics.png -------------------------------------------------------------------------------- /workshops/org-mode-litp/instructions.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Introduction to Literate Programming 2 | #+AUTHOR: Howard Abrams 3 | #+EMAIL: howard.abrams@gmail.com 4 | #+DATE: 2016 Feb 17 5 | #+TAGS: org-mode emacs presentation 6 | #+STARTUP: inlineimages yes 7 | #+PROPERTY: tangle no 8 | #+PROPERTY: eval no-export 9 | #+PROPERTY: results replace 10 | #+PROPERTY: exports code 11 | 12 | First of all, I would like to apologize for the examples. 13 | I need code and scripts in various languages that are short, simple to 14 | understand, not distracting, and useful. 15 | 16 | I sometimes can get one of those features. I would love better ones. 17 | 18 | * Background 19 | 20 | Before we dive into the org-mode specifics... 21 | 22 | ** Why Literate Programming 23 | 24 | - Literate Programming first invented by Donald Knuth in 1980’s 25 | 26 | - Emphasize /communication/ to people / team 27 | 28 | “Let us change our traditional attitude to the 29 | construction of programs. Instead of imagining that 30 | our main task is to instruct a computer what to do, 31 | let us concentrate rather on explaining to human 32 | beings what we want a computer to do.” —[[http://www.brainyquote.com/quotes/authors/d/donald_knuth.html#0RwBBIoWjqiKPb2Y.99][Donald Knuth]] 33 | 34 | - Inverted style from /code/ peppered with /comments/ 35 | 36 | - Never took off as an industry changer 37 | 38 | - Used (to various degrees) in niche circles 39 | 40 | ** What is Literate Programming 41 | 42 | * Programs are written for human understanding 43 | * Order based on logic of the problem (top-down) 44 | * Not constrained to deficiencies in the programming language 45 | 46 | * Comments are first-class citizens 47 | 48 | * Create a document for people *and* source code 49 | 50 | [[file:tangling-dark.png]] 51 | 52 | ** Literate Programming Example 53 | 54 | First, define a block of code with a /name/: 55 | 56 | #+BEGIN_EXAMPLE 57 | Every first program begins with baby steps, 58 | like the ubiquitous "hello world" example: 59 | 60 | <>= 61 | echo 'Hello, World!'; 62 | @ 63 | #+END_EXAMPLE 64 | 65 | Other blocks can /insert/ earlier blocks by name: 66 | 67 | #+BEGIN_EXAMPLE 68 | <>= 69 | > 72 | }> 73 | @ 74 | #+END_EXAMPLE 75 | 76 | ** Why Org? 77 | 78 | Knuth's /literate programming/ was /text with minimal support/ (=noweb=). 79 | 80 | One approach is [[http://ipython.org/notebook.html][iPython's notebook]], but we like /readable/ text files. 81 | 82 | We already use =org-mode= for everything else, right? 83 | 84 | If you buy into literate programming, org-mode is fookin' brilliant. 85 | 86 | “In the third millennium, does it still make sense 87 | to work with text files? Text files are the only truly 88 | portable format for files. The data will never get 89 | lost.” —[[http://transcriptvids.com/v/oJTwQvgfgMM.html][Carsten Dominik]] 90 | 91 | ** Advantages 92 | 93 | - Better documentation for your source code 94 | 95 | - Great for team communication over issues and problems 96 | 97 | - Clarify your own thoughts for complicated situations 98 | 99 | - Note-oriented REPL for investigating new libraries 100 | 101 | - Inter-language facility 102 | 103 | - Org's /organizational/ features, like Agendas 104 | 105 | ** Warnings 106 | 107 | - Programmers work in teams ... does everyone use Emacs? 108 | 109 | - Every programming language is treated /slightly/ differently 110 | 111 | - Knuth wanted to get around language limitations. 112 | Are we still limited? 113 | 114 | * Basics 115 | 116 | Fire up Emacs and let's try out the basics of working with source 117 | code in org-mode. 118 | 119 | ** Syntax Formatting 120 | 121 | Each *code block* has a typical syntax (format): 122 | 123 | #+NAME: 124 | #+BEGIN_SRC
125 | 126 | #+END_SRC 127 | 128 | The =language= is required, but the rest are optional. 129 | (Other than =BEGIN_SRC= and =END_SRC=) 130 | 131 | ** Basic Example 132 | 133 | - Open an org-mode file 134 | - Format it any way you wish 135 | - Create a source code block (case doesn't matter): 136 | 137 | #+BEGIN_SRC emacs-lisp 138 | (directory-files ".") 139 | #+END_SRC 140 | 141 | - Type =C-c C-c= to execute the command and see the results 142 | - Type =C-c ’= (apostrophe) to edit the block in your /mode/. 143 | 144 | ** Shortcuts 145 | 146 | If you are using a newer version of Emacs (not v22) or a later 147 | version of org-mode (installed from ELPA), use [[info:org#Easy%20Templates][Org Templates]]: 148 | 149 | - Create a block quickly by typing: == 302 | 303 | *Note:* You can set parameters when a /block is called/. 304 | We'll talk about this later. 305 | 306 | ** Too Many Parameters? 307 | 308 | Inline parameters with Header Block, fine with few parms: 309 | 310 | #+BEGIN_SRC sh :dir /etc 311 | grep $USER passwd 312 | #+END_SRC 313 | 314 | Lots of parameters? Move some (or /all/) parameters above: 315 | 316 | #+HEADER: :dir /etc 317 | #+BEGIN_SRC sh 318 | grep $USER passwd 319 | #+END_SRC 320 | 321 | These two section behave the same. 322 | 323 | Both =#+HEADER:= and =#+HEADERS:= behave the same. 324 | You can have more than one =#+HEADER:= line. 325 | 326 | ** Section Default Parameters 327 | 328 | Place header values for /all source blocks/ for a section in a 329 | *property drawer*: 330 | 331 | - Create a header section in your org file 332 | - Type: ~C-c C-x p~ 333 | - For =Property= enter: ~dir~ 334 | - For =Value= enter: ~/etc~ 335 | 336 | #+BEGIN_SRC ruby 337 | File.absolute_path(".") 338 | #+END_SRC 339 | 340 | #+RESULTS: 341 | : /etc 342 | 343 | Jump to the =:PROPERTIES:= drawer, and hit ~TAB~ to see the contents. 344 | 345 | ** Language-Specific Default Values 346 | :PROPERTIES: 347 | :header-args:sh: :dir /etc 348 | :header-args:ruby: :dir / 349 | :END: 350 | 351 | You can specify [[info:org#Language-specific%20header%20arguments%20in%20Org%20mode%20properties][language-specific header arguments]]: 352 | - Type: ~C-c C-x p~ 353 | - For =Property= enter: ~header-args:sh~ 354 | - For =Value= enter: ~:dir /etc 355 | - Type: ~C-c C-x p~ 356 | - For =Property= enter: ~header-args:ruby~ 357 | - For =Value= enter: ~:dir /~ 358 | 359 | #+BEGIN_SRC sh 360 | ls -d $(pwd) 361 | #+END_SRC 362 | 363 | #+RESULTS: 364 | : /etc 365 | 366 | #+BEGIN_SRC ruby 367 | File.absolute_path('.') 368 | #+END_SRC 369 | 370 | #+RESULTS: 371 | : / 372 | 373 | *Note:* Some parameters can only be set with =header-args= 374 | 375 | ** Default Parameters for Document 376 | 377 | To set a parameter for all blocks in a document, use the 378 | =#+PROPERTY:= setting: 379 | 380 | #+BEGIN_EXAMPLE 381 | #+PROPERTY: dir ~/Work 382 | #+END_EXAMPLE 383 | 384 | Notice these parameters do not have initial colon. 385 | 386 | Language specific ones, however, do: 387 | 388 | #+BEGIN_EXAMPLE 389 | #+PROPERTY: header-args:sh :tangle no 390 | #+END_EXAMPLE 391 | 392 | *Note:* They /aren't registered/ until you hit ~C-c C-c~ on them. 393 | 394 | #+BEGIN_EXAMPLE 395 | #+DESCRIPTION: A literate programming version of my Emacs Initialization script that is specific to this machine. 396 | #+PROPERTY: results silent 397 | #+PROPERTY: tangle ~/.emacs.d/elisp/init-local.el 398 | #+PROPERTY: eval no-export 399 | #+PROPERTY: comments org 400 | #+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil 401 | #+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil 402 | #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js 403 | #+END_EXAMPLE 404 | 405 | * Header Parameter Types 406 | 407 | Discussion of parameters revolve on usage: 408 | 409 | - Evaluation Parameters 410 | - Export Parameters 411 | - Literate Programming Parameters 412 | - Variable Parameters 413 | - Miscellaneous Input/Output 414 | 415 | * Evaluation Parameters 416 | ** Results 417 | 418 | When you execute a block, what do you want out of it? 419 | - results of the expression? 420 | - outputted results? 421 | 422 | #+BEGIN_SRC ruby 423 | puts 'Hello World' 424 | 5 * 6 425 | #+END_SRC 426 | 427 | #+RESULTS: 428 | : 30 429 | 430 | Change the [[info:org#Results%20of%20evaluation][:results]] header argument: 431 | 432 | #+BEGIN_SRC ruby :results output 433 | puts 'Hello World' 434 | 5 * 6 435 | #+END_SRC 436 | 437 | #+RESULTS: 438 | : Hello World 439 | 440 | *Note:* Default for =sh= is =output=. 441 | 442 | ** Output Formatting 443 | 444 | Results of code evaluation are re-inserted into your document. 445 | 446 | - =table= :: Row for single array, full table for array of arrays 447 | - =list= :: Regular org-mode list exported as an un-ordered list 448 | - =verbatim= :: Raw output 449 | - =file= :: Writes the results to a file 450 | - =html= :: Assumes the output is HTML code, and that is what is exported 451 | - =code= :: Assumes output is source code in the same language 452 | - =silent= :: Only shown in the mini-buffer 453 | 454 | Results can be exported (as in HTML, Email). 455 | 456 | Results can be used as /input variables/ to other code blocks. 457 | 458 | *** Lists 459 | 460 | Notice the previous output created a table. Let's make a list: 461 | 462 | #+BEGIN_SRC ruby :results list 463 | Dir.entries('.').sort.select do |file| 464 | file[0] != '.' 465 | end 466 | #+END_SRC 467 | 468 | #+RESULTS: 469 | - for-the-host.el 470 | - instructions.org 471 | - literate-programming-tangling.png 472 | - literate-programming-tangling2.png 473 | 474 | The Ruby code above is just an example. Use your favorite language 475 | to pull out a list of files from a directory. 476 | 477 | *** Raw Output 478 | 479 | Shell commands and log output are candidates. 480 | 481 | #+BEGIN_SRC sh :results verbatim :exports both 482 | ssh -v goblin.howardabrams.com ls mossandcrow 483 | #+END_SRC 484 | 485 | #+RESULTS: 486 | OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014 487 | debug1: Reading configuration data /etc/ssh/ssh_config 488 | debug1: /etc/ssh/ssh_config line 19: Applying options for * 489 | debug1: Connecting to goblin.howardabrams.com [162.243.135.186] port 22. 490 | debug1: Connection established. 491 | debug1: identity file /home/howard/.ssh/id_rsa type 1 492 | debug1: identity file /home/howard/.ssh/id_rsa-cert type -1 493 | debug1: identity file /home/howard/.ssh/id_dsa type -1 494 | debug1: identity file /home/howard/.ssh/id_dsa-cert type -1 495 | debug1: identity file /home/howard/.ssh/id_ecdsa type -1 496 | debug1: identity file /home/howard/.ssh/id_ecdsa-cert type -1 497 | debug1: identity file /home/howard/.ssh/id_ed25519 type -1 498 | debug1: identity file /home/howard/.ssh/id_ed25519-cert type -1 499 | debug1: Enabling compatibility mode for protocol 2.0 500 | debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.4 501 | debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 502 | debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 pat OpenSSH_6.6.1* compat 0x04000000 503 | debug1: SSH2_MSG_KEXINIT sent 504 | debug1: SSH2_MSG_KEXINIT received 505 | debug1: kex: server->client aes128-ctr hmac-md5-etm@openssh.com none 506 | debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com none 507 | debug1: sending SSH2_MSG_KEX_ECDH_INIT 508 | debug1: expecting SSH2_MSG_KEX_ECDH_REPLY 509 | debug1: Server host key: ECDSA 33:a5:af:64:c4:0a:84:6a:a8:57:5a:5f:69:13:08:85 510 | debug1: Host 'goblin.howardabrams.com' is known and matches the ECDSA host key. 511 | debug1: Found key in /home/howard/.ssh/known_hosts:2 512 | debug1: ssh_ecdsa_verify: signature correct 513 | debug1: SSH2_MSG_NEWKEYS sent 514 | debug1: expecting SSH2_MSG_NEWKEYS 515 | debug1: SSH2_MSG_NEWKEYS received 516 | debug1: SSH2_MSG_SERVICE_REQUEST sent 517 | debug1: SSH2_MSG_SERVICE_ACCEPT received 518 | debug1: Authentications that can continue: publickey,password 519 | debug1: Next authentication method: publickey 520 | debug1: Offering RSA public key: /home/howard/.ssh/id_rsa 521 | debug1: Server accepts key: pkalg ssh-rsa blen 279 522 | debug1: key_parse_private2: missing begin marker 523 | debug1: read PEM private key done: type RSA 524 | debug1: Authentication succeeded (publickey). 525 | Authenticated to goblin.howardabrams.com ([162.243.135.186]:22). 526 | debug1: channel 0: new [client-session] 527 | debug1: Requesting no-more-sessions@openssh.com 528 | debug1: Entering interactive session. 529 | debug1: Sending environment. 530 | debug1: Sending env LANG = en_US.UTF-8 531 | debug1: Sending command: ls mossandcrow 532 | debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 533 | debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0 534 | about.html 535 | contact.html 536 | examples.html 537 | img 538 | index.html 539 | scripts 540 | styles 541 | debug1: channel 0: free: client-session, nchannels 1 542 | debug1: fd 0 clearing O_NONBLOCK 543 | debug1: fd 1 clearing O_NONBLOCK 544 | Transferred: sent 3388, received 2616 bytes, in 0.6 seconds 545 | Bytes per second: sent 5588.8, received 4315.3 546 | debug1: Exit status 0 547 | 548 | ** Session 549 | 550 | Each block re-starts its interpreter. 551 | Use the [[info:org#session][:session]] header parameter as a label. 552 | 553 | Why? Issues include: 554 | 555 | - Large start-up time with large REP Ls ... like Clojure 556 | - Large start-up time on remote machines using Tramp 557 | - Maintaining functions and other state between blocks 558 | 559 | *Note:* Values can be passed between code blocks. 560 | 561 | *** Restarting Example 562 | 563 | To prove that interpreters are restarted with each block: 564 | 565 | #+BEGIN_SRC python 566 | answer = 42 567 | return answer 568 | #+END_SRC 569 | 570 | #+RESULTS: 571 | : 42 572 | 573 | #+BEGIN_SRC python 574 | return answer / 2 575 | #+END_SRC 576 | 577 | #+RESULTS: 578 | NameError: global name 'avar' is not defined 579 | 580 | *** Passing Consistency 581 | 582 | To prove that =:session=-based interpreters are /not/ restarted with 583 | each block: 584 | 585 | #+BEGIN_SRC ruby :session foobar 586 | avar = 42 587 | #+END_SRC 588 | 589 | #+RESULTS: 590 | : 42 591 | 592 | #+BEGIN_SRC ruby :session foobar 593 | avar / 2 594 | #+END_SRC 595 | 596 | #+RESULTS: 597 | : 21 598 | 599 | *Note:* The =:session= is good to set as a section property. 600 | 601 | Switch to the =*foobar*= buffer to interact with the interpreter. 602 | 603 | *Warning:* A named session can be shared across languages. 604 | 605 | *** Warning about Shared Sessions 606 | 607 | What's wrong with the following? 608 | 609 | **** Confusing Stuff 610 | :PROPERTIES: 611 | :session: stateful 612 | :END: 613 | 614 | #+BEGIN_SRC sh :results silent 615 | NUM_USERS=$(grep 'bash' /etc/passwd | wc -l --) 616 | #+END_SRC 617 | 618 | We have access to them: 619 | #+BEGIN_SRC sh 620 | echo $NUM_USERS 621 | #+END_SRC 622 | 623 | #+RESULTS: 624 | : 2 625 | 626 | #+BEGIN_SRC ruby 627 | 21 * 2 628 | #+END_SRC 629 | 630 | *Warning:* A =:session= setting for a section is shared for each 631 | block... /regardless of language!/ 632 | 633 | ** Writing Results to a File 634 | 635 | Create and evaluate this block: 636 | 637 | #+BEGIN_SRC ruby :results output :file primes.txt 638 | require 'prime' 639 | Prime.each(5000) do |prime| 640 | p prime 641 | end 642 | #+END_SRC 643 | 644 | Click on the link to load the file in a buffer. 645 | 646 | *Note:* The =:file= parameter needs =:results output= 647 | As it doesn't know how to format internal values 648 | 649 | * Exporting 650 | 651 | Hit ~C-c C-e h o~ to display your file in a browser. 652 | 653 | The [[info:org#exports][:exports]] header argument specifies what to export: 654 | - =code= for just the block 655 | - =results= for just the results to evaluating block 656 | - =both= for both code and results 657 | - =none= to ignore the block 658 | 659 | *Note:* The =:exports= is good to set as a section property. 660 | 661 | ** Syntax Highlighting for HTML 662 | 663 | To get syntax highlight for HTML exports, simply 664 | include the [[https://www.emacswiki.org/emacs/Htmlize][htmlize]] library: 665 | 666 | (require 'htmlize) 667 | 668 | Should come with recent versions of org-mode. 669 | Doesn't load? Install it from ELPA. 670 | 671 | * Literate Programming 672 | 673 | ** Tangling 674 | 675 | Takes all blocks of the same language, and writes into source file. 676 | 677 | #+BEGIN_SRC ruby :tangle double-space.rb 678 | while s = gets 679 | print s ; puts 680 | end 681 | #+END_SRC 682 | 683 | Type: ~C-c C-v t~ to render [[file:double-space.rb][double-space.rb]] 684 | 685 | With =:tangle yes= ... writes to file with same name as org file. 686 | 687 | Use =PROPERTY= to specify values for the /entire file/: 688 | 689 | #+BEGIN_EXAMPLE 690 | #+PROPERTY: tangle ~/.emacs.d/elisp/bling-mode.el 691 | #+END_EXAMPLE 692 | 693 | ** Comments 694 | 695 | If sharing source with others, have org prose turned into [[info:org#comments][comments]]: 696 | 697 | #+BEGIN_EXAMPLE 698 | Precede each line in the text from standard in (or file) with the 699 | current line number. 700 | See [[http://benoithamelin.tumblr.com/ruby1line][one liners]]. 701 | 702 | #+BEGIN_SRC ruby 703 | while s = gets 704 | puts "#{$<.file.lineno}: #{s}" 705 | end 706 | #+END_SRC 707 | 708 | #+PROPERTY: tangle lineno.rb 709 | #+PROPERTY: comments org 710 | #+END_EXAMPLE 711 | 712 | Gets turned into this Ruby script: 713 | 714 | #+BEGIN_EXAMPLE 715 | # Precede each line in the text from standard in (or file) with the 716 | # current line number. 717 | # See [[http://benoithamelin.tumblr.com/ruby1line][one liners]]. 718 | 719 | while s = gets 720 | puts "#{$<.file.lineno}: #{s}" 721 | end 722 | #+END_EXAMPLE 723 | 724 | ** Shebang 725 | 726 | When creating scripts, we often need to give it the initial 727 | interpreter to use. Here is specify the [[info:org#shebang][:shebang]] parameter (either 728 | as a block header or a document property): 729 | 730 | Precede each line in the text from standard in (or file) with the 731 | current line number. 732 | See [[http://benoithamelin.tumblr.com/ruby1line][one liners]]. 733 | 734 | #+BEGIN_SRC ruby :shebang "#!/bin/ruby" 735 | while s = gets 736 | puts "#{$<.file.lineno}: #{s}" 737 | end 738 | #+END_SRC 739 | 740 | #+PROPERTY: shebang #!/bin/ruby 741 | #+PROPERTY: tangle lineno 742 | #+PROPERTY: comments org 743 | 744 | Works as expected: 745 | 746 | #+BEGIN_EXAMPLE 747 | #!/bin/ruby 748 | # Precede each line in the text from standard in (or file) with the 749 | # current line number. 750 | # See [[http://benoithamelin.tumblr.com/ruby1line][one liners]]. 751 | 752 | while s = gets 753 | puts "#{$<.file.lineno}: #{s}" 754 | end 755 | #+END_EXAMPLE 756 | 757 | ** Noweb 758 | 759 | If you /name/ a block, you can /include/ that block *inside* another 760 | block... as text, using [[info:org#noweb][:noweb]]. Consider this org-mode file: 761 | 762 | Print the last field of each line. 763 | 764 | #+NAME: the-script 765 | #+BEGIN_SRC ruby 766 | puts $F.last 767 | #+END_SRC 768 | 769 | #+BEGIN_SRC sh :noweb yes :tangle last-col.sh 770 | ruby -ane '<>' 771 | #+END_SRC 772 | 773 | Creates [[file:last-col.sh][last-col.sh]] that contains: 774 | 775 | #+BEGIN_EXAMPLE 776 | ruby -ane 'puts $F.last' 777 | #+END_EXAMPLE 778 | 779 | ** Usefulness? 780 | 781 | How useful is this? 782 | 783 | Older languages that Donald Knuth used, required all variables and 784 | functions to be defined before used. This meant, you always wrote 785 | code, /bottom-up/. 786 | 787 | Some code may be better explained from a /top-down/ approach. 788 | The /web and tangling/ approach could work well for some algorithms. 789 | 790 | Modern languages often don't have such limitations. 791 | 792 | ** Noweb Considerations 793 | 794 | What about multi-line blocks? 795 | 796 | #+NAME: prime 797 | #+BEGIN_SRC ruby 798 | require "prime" 799 | Prime.prime?(ARG[0]) 800 | #+END_SRC 801 | 802 | #+BEGIN_SRC ruby :noweb yes :tangle primes.sh 803 | cat $* | xargs ruby -ne '<>' 804 | #+END_SRC 805 | 806 | Treats the /preceding text/ like /initial comment characters/: 807 | 808 | #+BEGIN_EXAMPLE 809 | cat $* | xargs ruby -ne 'require "prime" 810 | cat $* | xargs ruby -ne 'Prime.prime?(ARG[0])' 811 | #+END_EXAMPLE 812 | 813 | This recent change requires [[http://ss64.com/bash/syntax-here.html][here docs]] or single quotes: 814 | 815 | #+BEGIN_SRC sh :noweb yes :tangle primes2.sh 816 | cat $* | xargs ruby -ne ' 817 | <>' 818 | #+END_SRC 819 | 820 | * Variables 821 | 822 | Org can pass in one or move values /into your source block/ as a variable. 823 | 824 | ** Variable Example 825 | 826 | Build this block and execute it with ~C-c C-c~: 827 | 828 | #+BEGIN_SRC python :var interest=13 829 | return 313 * (interest / 100.0) 830 | #+END_SRC 831 | 832 | #+RESULTS: 833 | : 40.69 834 | 835 | Pythonic precision for the win. 836 | 837 | ** Setting Variables 838 | 839 | Specify multiple values all over the place: 840 | 841 | #+HEADER: :var a=42 d=56 :var f=23 842 | #+HEADERS: :var b=79 e=79 843 | #+BEGIN_SRC ruby :var c=3 g=2 844 | [ a, b, c, d, e, f, g ] 845 | #+END_SRC 846 | 847 | #+RESULTS: 848 | | 42 | 79 | 3 | 56 | 79 | 23 | 2 | 849 | 850 | How useful is this? 851 | 852 | Allows you to verify a /block of code/ with values that are not 853 | tangled. 854 | 855 | ** Block-to-Block Value Passing 856 | 857 | First, name your block: 858 | 859 | #+NAME: twelve-primes 860 | #+BEGIN_SRC ruby 861 | require 'prime' 862 | Prime.first 12 863 | #+END_SRC 864 | 865 | #+RESULTS: twelve-primes 866 | | 2 | 3 | 5 | 7 | 11 | 13 | 17 | 19 | 23 | 29 | 31 | 37 | 867 | 868 | Pass them into another code block as an /array/ variable: 869 | 870 | #+BEGIN_SRC python :var primes=twelve-primes 871 | return primes[-1] 872 | #+END_SRC 873 | 874 | First time Ruby and Python has worked together. 875 | 876 | ** Tabular Variable Data 877 | 878 | Need to create a table of numbers to use in following sections: 879 | 880 | #+NAME: cool-numbers 881 | #+BEGIN_SRC emacs-lisp 882 | (mapcar (lambda (i) 883 | (list i (random 10) 884 | (expt i 2) (random 100) 885 | (expt i 3) (random 1000))) 886 | (number-sequence 1 10)) 887 | #+END_SRC 888 | 889 | While you can make a table of number any way you wish (in whatever 890 | language tickles your fancy). Here's a Pythonista version: 891 | #+BEGIN_SRC python 892 | import random 893 | return [[i, random.randint(1, 10), 894 | i ** 2, random.randint(1, 100), 895 | i ** 3, random.randint(1, 1000)] for i in range(1, 10)] 896 | #+END_SRC 897 | 898 | One for the Rubyists: 899 | #+BEGIN_SRC ruby 900 | (1..10).collect do |i| 901 | [ i, rand(10), i ** 2, rand(100), i ** 3, rand(1000) ] 902 | end 903 | #+END_SRC 904 | 905 | JavaScript anyone? 906 | 907 | #+BEGIN_SRC js 908 | var __ = require('lodash'); 909 | __.map(__.range(1, 10), 910 | function(i) { 911 | return [i, __.random(1, 10), 912 | Math.pow(i, 2), __.random(1, 100), 913 | Math.pow(i, 3), __.random(1, 1000) ] 914 | }); 915 | #+END_SRC 916 | 917 | And a token gesture for the Clojurians: 918 | 919 | #+BEGIN_SRC clojure 920 | (map #(list % (rand-int 10) 921 | (* % %) (rand-int 100) 922 | (* % % %) (rand-int 1000)) 923 | (range 1 10)) 924 | #+END_SRC 925 | 926 | ** List of Lists 927 | 928 | Grabbing our table gives our block an array of arrays: 929 | 930 | #+BEGIN_SRC python :var nums=cool-numbers :results list 931 | return [ cell + 1 for row in nums for cell in row ] 932 | #+END_SRC 933 | 934 | Here it takes the two dimensional matrix, puts it into one long 935 | list, and adds one to every number. 936 | 937 | ** Slicing and Dicing Tables 938 | 939 | We can get just a single row from a table: 940 | 941 | #+BEGIN_SRC ruby :var fifth=cool-numbers[4] 942 | fifth 943 | #+END_SRC 944 | 945 | We can also get just a single column: 946 | 947 | #+NAME: cubes 948 | #+BEGIN_SRC elisp :var cubes=cool-numbers[,4] 949 | cubes 950 | #+END_SRC 951 | 952 | ** Reprocessing 953 | 954 | The =cool-numbers= was used in the =cubes= block, and we can use that 955 | again: 956 | 957 | #+NAME: roots_of_list 958 | #+BEGIN_SRC python :var lst=cubes :results list 959 | import math 960 | return [ math.sqrt(n) for n in lst ] 961 | #+END_SRC 962 | 963 | * Keeping your Blocks Clean 964 | 965 | A block of code /does/ something 966 | but 967 | A block of code also /communicates/ something 968 | 969 | Try to keep necessary code that doesn't help communicate out. 970 | 971 | ** Cleaning Results 972 | 973 | Clean the output from code block using [[info:org#post][:post]] parameter. 974 | Yeah, this could have been part of the *Exports* section. 975 | 976 | The =ls -l= prepends a =total= line, we create a /processor/ to return 977 | all lines except the first. Notice, my variable, =data=: 978 | 979 | #+NAME: skip_first 980 | #+BEGIN_SRC elisp :var data="" 981 | (cdr data) 982 | #+END_SRC 983 | 984 | The /results/ from the code block is assigned to =*this*= which I 985 | assign to the =data= variable: 986 | 987 | #+BEGIN_SRC sh :post skip_first(data=*this*) 988 | ls -l 989 | #+END_SRC 990 | 991 | #+RESULTS: 992 | | -rw-rw-r-- | 1 | howard | howard | 404 | Mar | 15 | 20:55 | agenda.org | 993 | | -rw-rw-r-- | 1 | howard | howard | 14 | Feb | 23 | 10:03 | double-line2.sh | 994 | | -rw-rw-r-- | 1 | howard | howard | 33 | Feb | 23 | 09:20 | double-line.sh | 995 | | -rw-rw-r-- | 1 | howard | howard | 12 | Feb | 23 | 07:21 | double-space.rb | 996 | | -rw-rw-r-- | 1 | howard | howard | 4893 | Mar | 15 | 21:50 | for-the-host.el | 997 | | -rw-rw-r-- | 1 | howard | howard | 9611 | Mar | 3 | 20:04 | graphics.png | 998 | | -rw-rw-r-- | 1 | howard | howard | 33810 | Mar | 16 | 06:56 | instructions.org | 999 | ... 1000 | 1001 | ** Environment Setup 1002 | 1003 | Connection information to OpenStack set in resource files: 1004 | 1005 | #+BEGIN_EXAMPLE 1006 | $ source openrc 1007 | $ nova list 1008 | #+END_EXAMPLE 1009 | 1010 | Put necessary but unsightly code in [[info:org#prologue][:prologue]] sections: 1011 | 1012 | #+HEADER: :prologue "source openrc" 1013 | #+BEGIN_SRC sh 1014 | nova list 1015 | #+END_SRC 1016 | 1017 | Code in the =:prologue= will not be exported. 1018 | 1019 | ** Using RVM 1020 | 1021 | Languages like Python and Ruby often want a /virtual machine/ to 1022 | specify how something should be processed. You can use =:prologue= 1023 | with two backslashes to pre-pend it (for shell calls anyway): 1024 | 1025 | #+BEGIN_SRC sh :prologue "~/.rvm/bin/rvm 1.9.3@msw exec \\" 1026 | gem list 1027 | #+END_SRC 1028 | 1029 | *Note:* Execution of Ruby or Python code is based on the [[http://www.emacswiki.org/emacs/RvmEl][rvm]], or 1030 | [[http://github.com/jorgenschaefer/pyvenv][pyvenv]] or [[https://github.com/jorgenschaefer/elpy/wiki][ELPY]]. 1031 | 1032 | * Miscellaneous Features 1033 | ** Calling Blocks 1034 | 1035 | Remember our =roots_of_list= block we [[*Reprocessing][created above]]? 1036 | It took a variable, =lst=. 1037 | 1038 | #+CALL: roots_of_list( lst='(16 144 81 61) ) 1039 | 1040 | #+Results: 1041 | | 4.0 | 12.0 | 9.0 | 7.810249675906654 | 1042 | 1043 | Do it again, but with our =cool-numbers= table: 1044 | 1045 | #+CALL: roots_of_list( lst=cool-numbers[,2] ) 1046 | 1047 | #+RESULTS: 1048 | | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 | 6.0 | 7.0 | 8.0 | 9.0 | 10.0 | 1049 | 1050 | We can /push/ values into blocks or a block can /pull/ values. 1051 | 1052 | *Note:* You can set header parameters /inside brackets/. 1053 | See [[info:org#Evaluating%20code%20blocks][info:org#Evaluating code blocks]] for details. 1054 | 1055 | ** Cleaning Results 1056 | 1057 | Clean the output from code block using [[info:org#post][:post]] parameter. 1058 | 1059 | The =ls -l= prepends a =total= line, we create a /processor/ to return 1060 | all lines except the first. Notice, my variable, =data=: 1061 | 1062 | #+NAME: skip_first 1063 | #+BEGIN_SRC elisp :var data="" 1064 | (cdr data) 1065 | #+END_SRC 1066 | 1067 | The /results/ from the code block is assigned to =*this*= which I 1068 | assign to the =data= variable: 1069 | 1070 | #+BEGIN_SRC sh :post skip_first(data=*this*) 1071 | ls -l 1072 | #+END_SRC 1073 | 1074 | ** Library of Babel 1075 | 1076 | The /Library of Babel/ is one or more files containing one or more 1077 | /named blocks/ that are accessible to any org-mode file. 1078 | 1079 | - Create and save file of named blocks 1080 | - Once in your Emacs session: ~C-c C-v i~ 1081 | - Select your /babel/ file. 1082 | - Or, call: =org-babel-lob-ingest= with each file 1083 | 1084 | These are really good: 1085 | - for =:post= processing output 1086 | - for =#+CALL= where you want just the results 1087 | 1088 | ** One Liners 1089 | 1090 | If you want a quickly evaluated result from a language: 1091 | 1092 | - src_ruby{ 5+6 } =11= 1093 | - src_elisp{ org-agenda-files } 1094 | - src_sh{ ls } 1095 | 1096 | When exported, only /results/ are shown (not the source). 1097 | 1098 | Also supports /calling/ blocks too: 1099 | 1100 | call_roots_of_list( lst=cool-numbers[,2] ) 1101 | | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 | 6.0 | 7.0 | 8.0 | 9.0 | 10.0 | 1102 | 1103 | * Specialized Languages 1104 | ** Graphviz 1105 | 1106 | If you have [[http://www.graphviz.org/][Graphviz]] installed: 1107 | 1108 | #+BEGIN_SRC dot :file graphics.png 1109 | digraph { 1110 | a -> b; 1111 | b -> c: 1112 | d -> a; 1113 | } 1114 | #+END_SRC 1115 | 1116 | [[file:graphics.png]] 1117 | 1118 | *Note:* To /edit/ the code, the language is =graphviz-dot= 1119 | To /run/ the code, the language is =dot= 1120 | 1121 | ** PlantUML 1122 | 1123 | If you have [[http://plantuml.sourceforge.net/download.html][PlantUML]] installed: 1124 | 1125 | #+BEGIN_SRC plantuml :file sequence-diagram.png 1126 | @startuml sequence-diagram.png 1127 | 1128 | Alice -> Bob: synchronous call 1129 | Alice ->> Bob: asynchronous call 1130 | 1131 | @enduml 1132 | #+END_SRC 1133 | 1134 | [[file:sequence-diagram.png]] 1135 | 1136 | ** Calc 1137 | 1138 | Access the [[info:calc#Top][Emacs Calculator]] as well. 1139 | You may need to load it: ~M-x load-library~ and type: ~ob-calc~ 1140 | 1141 | #+BEGIN_SRC calc :var a=2 b=9 c=64 x=5 1142 | ((a+b)^3 + sqrt(c)) / (2x+1) 1143 | #+END_SRC 1144 | 1145 | #+RESULTS: 1146 | : 121.727272727 1147 | 1148 | Or simplify the formula: 1149 | 1150 | #+BEGIN_SRC calc :var a=4 b=2 1151 | ((a+b)^3 + sqrt(c)) / (2x+1) 1152 | #+END_SRC 1153 | 1154 | #+RESULTS: 1155 | : (sqrt(c) + 216) / (2 x + 1) 1156 | 1157 | * Summary 1158 | 1159 | Each source code block allows [[info:org#Specific%20header%20arguments][header arguments]]. What is your goal? 1160 | 1161 | - *Code Evaluation?* 1162 | - [[info:org#dir][dir]] :: specify directory the code should run ... Tramp? 1163 | - [[info:org#session][session]] :: re-use interpreter between code blocks 1164 | - [[info:org#file][file]] :: write results to the file system 1165 | - [[info:org#eval][eval]] :: limit evaluation of specific code blocks 1166 | - [[info:org#cache][cache]] :: cache eval results to avoid re-evaluation of blocks 1167 | - [[info:org#var][var]] :: setting variables for a block (ignore with no-expand) 1168 | 1169 | - *Exporting?* 1170 | - [[info:org#results][results]] :: either =output= or =value= and the formatting 1171 | - [[info:org#exports][exports]] :: how the code and results should be exported 1172 | 1173 | - *Literate Programming?* 1174 | - [[info:org#tangle][tangle]] :: how the source written to a script file ... this is 1175 | literate programming. 1176 | - [[info:org#mkdirp][mkdirp]] :: create parent directory of tangled source file 1177 | - [[info:org#shebang][shebang]] :: the initial line written to tangled files 1178 | - [[info:org#noweb][noweb]] :: toggle expansion of noweb references 1179 | - [[info:org#noweb-ref][noweb-ref]] :: resolution target for noweb references 1180 | 1181 | - Special Input? 1182 | - [[info:org#prologue][prologue]] :: text to prepend to code block body 1183 | - [[info:org#epilogue][epilogue]] :: text to append to code block body 1184 | 1185 | - Special Output and Formatting? 1186 | - [[info:org#padline][padline]] :: 1187 | - [[info:org#post][post]] :: post processing of code block results 1188 | - [[info:org#wrap][wrap]] :: 1189 | - Misc. :: [[info:org#hlines][hlines]], [[info:org#colnames][colnames]], [[info:org#rownames][rownames]] 1190 | 1191 | ** Ignore This 1192 | 1193 | #+BEGIN_SRC ruby 1194 | def fibonacci(n) 1195 | n <= 1 ? n : fibonacci( n - 1 ) + fibonacci( n - 2 ) 1196 | end 1197 | 1198 | def factorial(n) 1199 | (1..n).inject(1, :*) 1200 | end 1201 | 1202 | (1..10).collect do |i| 1203 | [ i, i*i, i**3, factorial(i), fibonacci(i) ] 1204 | end 1205 | #+END_SRC 1206 | 1207 | Need to generate some diagrams, right? 1208 | 1209 | #+BEGIN_SRC dot :file tangling.png :cmdline -Kdot -Tpng 1210 | digraph G { 1211 | bgcolor="transparent" 1212 | node [fontname="helvetica-bold" fontsize=24] 1213 | 1214 | node [label="LP File"] B 1215 | node [label="Source Code"] S 1216 | node [label="Documentation"] D 1217 | 1218 | B -> D 1219 | B -> S 1220 | } 1221 | #+END_SRC 1222 | 1223 | #+BEGIN_SRC dot :file tangling-dark.png :cmdline -Kdot -Tpng 1224 | digraph G { 1225 | bgcolor="transparent" 1226 | node [style="filled" color="white" fontname="helvetica-bold" fontsize=24] 1227 | edge [color="white"] 1228 | 1229 | node [label="LP File"] B 1230 | node [label="Source Code"] S 1231 | node [label="Documentation"] D 1232 | 1233 | B -> D 1234 | B -> S 1235 | } 1236 | #+END_SRC 1237 | 1238 | Note: To evaluate the diagram and render a picture, change the 1239 | =graphviz-dot= language to just =dot= 1240 | -------------------------------------------------------------------------------- /workshops/org-mode-litp/literate-programming-tangling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/workshops/org-mode-litp/literate-programming-tangling.png -------------------------------------------------------------------------------- /workshops/org-mode-litp/literate-programming-tangling2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/workshops/org-mode-litp/literate-programming-tangling2.png -------------------------------------------------------------------------------- /workshops/org-mode-litp/requirements.org: -------------------------------------------------------------------------------- 1 | * Requirements 2 | 3 | You will need: 4 | - *Emacs*, =v23= or better (I really suggest =v24.4= or better) 5 | Type: ~C-h v~ and ~emacs-version~ 6 | 7 | - *org-mode*, =v8.2.10= 8 | Type: ~C-h v~ and ~org-version~ 9 | Install: ~M-x package-refresh-contents~ 10 | ~M-x package-install~ and ~org~ 11 | 12 | - *Python* and *Ruby* for programming examples 13 | (or be good at translating into your favorite language) 14 | 15 | *Note:* Please /pair/ with a partner... 16 | -------------------------------------------------------------------------------- /workshops/org-mode-litp/sequence-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/workshops/org-mode-litp/sequence-diagram.png -------------------------------------------------------------------------------- /workshops/org-mode-litp/tangling-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/workshops/org-mode-litp/tangling-dark.png -------------------------------------------------------------------------------- /workshops/org-mode-litp/tangling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/pdx-emacs-hackers/bfb7bd640fdf0ce3def21f9fc591ed35d776b26d/workshops/org-mode-litp/tangling.png --------------------------------------------------------------------------------