From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?utf-8?Q?S=C3=A9bastien_Vauban?= Subject: [babel] How to kill two birds with one stone? Date: Fri, 04 Feb 2011 17:00:33 +0100 Message-ID: <808vxv23j2.fsf@missioncriticalit.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Return-path: List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org-mXXj517/zsQ@public.gmane.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org-mXXj517/zsQ@public.gmane.org To: emacs-orgmode-mXXj517/zsQ@public.gmane.org #+TITLE: Document a shell script as separate blocks #+DATE: 2011-02-04 #+LANGUAGE: en_US * Abstract When writing shell scripts, I'd like to kill *two* birds with one Babel sto= ne: - Be able to *execute the script in situ*, so that I get a copy of the resu= lts stored in (and "versioned" with) my documentation. - Be able to *chain the code blocks*, so that I tangle a "natural" script i= nto a file for later execution. I guess I currently miss some points in order to reach that goal in a clean way. Could you give me advice on how to get a step further down the route? * Sample code For the sake of clarity, let's take a simple problem: I'd like to generate a DOT graph of links between all files from a directory tree. The procedure: 1. (Recursively) list all files inside the directory. 2. For each file, (recursively) search for its name referenced in all the files. 3. Generate a DOT representation of the link between files. ** List all files under current directory #+srcname: dw-file-tree #+begin_src sh :results output cd ~/Some-Project-Dir find . -type f -print | grep -v .svn | head -n 5 #+end_src #+results: dw-file-tree #+begin_example ./.cvsignore ./charge_dim ./charge_fct ./compte ./controle_config #+end_example Here, I voluntary limit the number of results to the first 5 files, for the compactness of this example. This sample does not include any file from subdirectories, but it doesn't matter. ** Search recursively for anything about a file Search through all files (ignoring =3D.svn=3D directories) for any referenc= e to filename given as parameter. #+srcname: search-files-pointing-to-this-file #+begin_src sh :results output :var f=3D"charge_dim" cd ~/Some-Project-Dir find . -not \( -name .svn -prune \) -type f -print0 |\ xargs -0 grep -i --files-with-matches "$f" #+end_src #+results: search-files-pointing-to-this-file #+begin_example ./.cvsignore ./charge_dim ./compte ./IFP/Chrg_dim ./IFP/Chrg_dim.avant_simple_recovery_mode_2008_03_12 ./principal.env ./29Aalst/Chrg_dim ./29Aalst/Chrg_dim_interactif ./29Aalst/Publ_dim_interactif #+end_example HERE, I'M GIVING A FILENAME AS DEFAULT VALUE OF =3Df=3D IN ORDER TO SEE A S= AMPLE RESULTS. ** Convert to a DOT representation For every file pointing to the file given in parameter, generate an "arrow" (edge) in DOT representation. #+srcname: dot-arrow-from-files-pointing-to-this-file #+begin_src sh :results output :var f=3D"charge_dim" :var data=3Dsearch-fil= es-pointing-to-this-file for i in $(echo "$data"); do echo " $(basename $i) -> $f"; done #+end_src #+results: dot-arrow-from-files-pointing-to-this-file #+begin_example .cvsignore -> charge_dim charge_dim -> charge_dim compte -> charge_dim Chrg_dim -> charge_dim Chrg_dim.avant_simple_recovery_mode_2008_03_12 -> charge_dim principal.env -> charge_dim Chrg_dim -> charge_dim Chrg_dim_interactif -> charge_dim Publ_dim_interactif -> charge_dim #+end_example HERE, I'M WORKING GIVING ONCE AGAIN THE SAME DEFAULT VALUE FOR TESTING (AND DOCUMENTATION) PURPOSE. * Problem All of the above nicely answer my first goal ("Be able to execute the script in situ, so that I get a copy of the results stored in my documentation"). It does not allow for the second one: *how to chain the calls together*? For example, just for chaining steps 2 and 3 (the easier to chain, I think), I'd like to be able to write something like this: #+srcname: search-links-and-generate-dot-arrow #+begin_src sh :results output :var f=3D"charge_dim" :var data=3Dsearch-fil= es-pointing-to-this-file :noweb yes for i in ( <>); do echo " $(basename $i) -> $f"; done #+end_src #+results: search-links-and-generate-dot-arrow But it yields an error: #+begin_src text :eval no sh: line 14: syntax error near unexpected token `(' sh: line 14: `for i in (' #+end_src Note, in the latter code block, that I did not even tried to really chain steps 2 and 3: I'm rewriting step 3, including step 2 inside it. *I certainly miss a smarter way* to achieve the above. Quite important as well, is that the tangled file seems natural to read (for someone that would not read it from the Org file). This means we would have= to minimize the use of "echo" and "tee" commands, among others -- but that's a nice to have. Do you see my point? Do you have ideas on how to go that way? Best regards, Seb --=20 S=C3=A9bastien Vauban _______________________________________________ Emacs-orgmode mailing list Please use `Reply All' to send replies to the list. Emacs-orgmode-mXXj517/zsQ@public.gmane.org http://lists.gnu.org/mailman/listinfo/emacs-orgmode