Browse Source

Merge branch 'master' of orgmode.org:org-mode

Carsten Dominik 14 years ago
parent
commit
ed02a6f8d1
7 changed files with 187 additions and 122 deletions
  1. 45 19
      doc/org.texi
  2. 1 47
      lisp/ob-tangle.el
  3. 35 29
      lisp/ob.el
  4. 57 23
      lisp/org-agenda.el
  5. 4 4
      lisp/org-indent.el
  6. 28 0
      testing/examples/babel.org
  7. 17 0
      testing/lisp/test-ob-tangle.el

+ 45 - 19
doc/org.texi

@@ -11549,23 +11549,6 @@ Tangle the current file.  Bound to @kbd{C-c C-v t}.
 Choose a file to tangle.   Bound to @kbd{C-c C-v f}.
 Choose a file to tangle.   Bound to @kbd{C-c C-v f}.
 @end table
 @end table
 
 
-@subsubheading Variables
-@table @code
-@item org-babel-tangle-named-block-combination
-This variable controls the tangling of multiple code blocks with the same
-name.
-@table @code
-@item nil
-The default behavior.  Blocks with the same name are tangled as normal.
-@item append
-The bodies of all blocks of the same name are appended during tangling.
-@item first
-Only the body of the first block of any given name is kept during tangling.
-@item last
-Only the body of the last block of any given name is kept during tangling.
-@end table
-@end table
-
 @subsubheading Hooks
 @subsubheading Hooks
 @table @code
 @table @code
 @item org-babel-post-tangle-hook
 @item org-babel-post-tangle-hook
@@ -11946,6 +11929,7 @@ The following header arguments are defined:
                                 expansion during tangling
                                 expansion during tangling
 * session::                     Preserve the state of code evaluation
 * session::                     Preserve the state of code evaluation
 * noweb::                       Toggle expansion of noweb references
 * noweb::                       Toggle expansion of noweb references
+* noweb-ref::                   Specify block's noweb reference resolution target
 * cache::                       Avoid re-evaluating unchanged code blocks
 * cache::                       Avoid re-evaluating unchanged code blocks
 * sep::                         Delimiter for writing tabular results outside Org
 * sep::                         Delimiter for writing tabular results outside Org
 * hlines::                      Handle horizontal lines in tables
 * hlines::                      Handle horizontal lines in tables
@@ -12466,7 +12450,7 @@ A string passed to the @code{:session} header argument will give the session
 a name.  This makes it possible to run concurrent sessions for each
 a name.  This makes it possible to run concurrent sessions for each
 interpreted language.
 interpreted language.
 
 
-@node noweb, cache, session, Specific header arguments
+@node noweb, noweb-ref, session, Specific header arguments
 @subsubsection @code{:noweb}
 @subsubsection @code{:noweb}
 
 
 The @code{:noweb} header argument controls expansion of ``noweb'' style (see
 The @code{:noweb} header argument controls expansion of ``noweb'' style (see
@@ -12512,7 +12496,49 @@ Note that noweb replacement text that does not contain any newlines will not
 be affected by this change, so it is still possible to use inline noweb
 be affected by this change, so it is still possible to use inline noweb
 references.
 references.
 
 
-@node cache, sep, noweb, Specific header arguments
+@node noweb-ref, cache, noweb, Specific header arguments
+@subsubsection @code{:noweb-ref}
+When expanding ``noweb'' style references the bodies of all code block with
+@emph{either} a block name matching the reference name @emph{or} a
+@code{:noweb-ref} header argument matching the reference name will be
+concatenated together to form the replacement text.
+
+By setting this header argument at the sub-tree or file level, simple code
+block concatenation may be achieved.  For example, when tangling the
+following Org-mode file, the bodies of code blocks will be concatenated into
+the resulting pure code file.
+
+@example
+ #+begin_src sh :tangle yes :noweb yes :shebang #!/bin/sh
+   <<fullest-disk>>
+ #+end_src
+ * the mount point of the fullest disk
+   :PROPERTIES:
+   :noweb-ref: fullest-disk
+   :END:
+
+ ** query all mounted disks
+ #+begin_src sh
+   df \
+ #+end_src
+
+ ** strip the header row
+ #+begin_src sh
+   |sed '1d' \
+ #+end_src
+
+ ** sort by the percent full
+ #+begin_src sh
+   |awk '@{print $5 " " $6@}'|sort -n |tail -1 \
+ #+end_src
+
+ ** extract the mount point
+ #+begin_src sh
+   |awk '@{print $2@}'
+ #+end_src
+@end example
+
+@node cache, sep, noweb-ref, Specific header arguments
 @subsubsection @code{:cache}
 @subsubsection @code{:cache}
 
 
 The @code{:cache} header argument controls the use of in-buffer caching of
 The @code{:cache} header argument controls the use of in-buffer caching of

+ 1 - 47
lisp/ob-tangle.el

@@ -96,15 +96,6 @@ controlled by the :comments header argument."
   :group 'org-babel
   :group 'org-babel
   :type 'string)
   :type 'string)
 
 
-(defcustom org-babel-tangle-named-block-combination nil
-  "Combine blocks of the same name during tangling."
-  :group 'org-babel
-  :type '(choice
-	  (const :tag "Default: no special handling" nil)
-	  (const :tag "Append all blocks of the same name" append)
-	  (const :tag "Only keep the first block of the same name" first)
-	  (const :tag "Only keep the last block of the same name" last)))
-
 (defun org-babel-find-file-noselect-refresh (file)
 (defun org-babel-find-file-noselect-refresh (file)
   "Find file ensuring that the latest changes on disk are
   "Find file ensuring that the latest changes on disk are
 represented in the file."
 represented in the file."
@@ -249,8 +240,7 @@ exported source code blocks by language."
                     (setq block-counter (+ 1 block-counter))
                     (setq block-counter (+ 1 block-counter))
                     (add-to-list 'path-collector file-name)))))
                     (add-to-list 'path-collector file-name)))))
             specs)))
             specs)))
-       (org-babel-tangle-combine-named-blocks
-	(org-babel-tangle-collect-blocks lang)))
+       (org-babel-tangle-collect-blocks lang))
       (message "tangled %d code block%s from %s" block-counter
       (message "tangled %d code block%s from %s" block-counter
                (if (= block-counter 1) "" "s")
                (if (= block-counter 1) "" "s")
 	       (file-name-nondirectory
 	       (file-name-nondirectory
@@ -372,42 +362,6 @@ code blocks by language."
 	   blocks))
 	   blocks))
     blocks))
     blocks))
 
 
-(defun org-babel-tangle-combine-named-blocks (blocks)
-  "Combine blocks of the same name.
-This function follows noweb behavior of appending blocks of the
-same name in the order they appear in the file."
-  (if org-babel-tangle-named-block-combination
-      (let (tangled-names)
-	(mapcar
-	 (lambda (by-lang)
-	   (cons
-	    (car by-lang)
-	    (mapcar (lambda (spec)
-		      (let ((name (nth 3 spec)))
-			(unless (member name tangled-names)
-			  (when name
-			    (setf
-			     (nth 5 spec)
-			     (let ((named (mapcar
-					   (lambda (el) (nth 5 el))
-					   (delq
-					    nil
-					    (mapcar
-					     (lambda (el)
-					       (when (equal name (nth 3 el))
-						 el))
-					     (cdr by-lang))))))
-			       (case org-babel-tangle-named-block-combination
-				 (append (mapconcat #'identity
-						    named ""))
-				 (first  (first named))
-				 (last   (car (last  named))))))
-			    (add-to-list 'tangled-names name))
-			  spec)))
-		    (cdr by-lang))))
-	 blocks))
-    blocks))
-
 (defun org-babel-spec-to-string (spec)
 (defun org-babel-spec-to-string (spec)
   "Insert SPEC into the current file.
   "Insert SPEC into the current file.
 Insert the source-code specified by SPEC into the current
 Insert the source-code specified by SPEC into the current

+ 35 - 29
lisp/ob.el

@@ -291,7 +291,8 @@ then run `org-babel-pop-to-session'."
 
 
 (defconst org-babel-header-arg-names
 (defconst org-babel-header-arg-names
   '(cache cmdline colnames dir exports file noweb results
   '(cache cmdline colnames dir exports file noweb results
-    session tangle var eval noeval comments no-expand shebang padline)
+    session tangle var eval noeval comments no-expand shebang
+    padline noweb-ref)
   "Common header arguments used by org-babel.
   "Common header arguments used by org-babel.
 Note that individual languages may define their own language
 Note that individual languages may define their own language
 specific header arguments as well.")
 specific header arguments as well.")
@@ -1842,13 +1843,21 @@ block but are passed literally to the \"example-block\"."
          (lang (nth 0 info))
          (lang (nth 0 info))
          (body (nth 1 info))
          (body (nth 1 info))
 	 (comment (string= "noweb" (cdr (assoc :comments (nth 2 info)))))
 	 (comment (string= "noweb" (cdr (assoc :comments (nth 2 info)))))
-         (new-body "") index source-name evaluate prefix)
+         (new-body "") index source-name evaluate prefix blocks-in-buffer)
     (flet ((nb-add (text) (setq new-body (concat new-body text)))
     (flet ((nb-add (text) (setq new-body (concat new-body text)))
 	   (c-wrap (text)
 	   (c-wrap (text)
 		   (with-temp-buffer
 		   (with-temp-buffer
 		     (funcall (intern (concat lang "-mode")))
 		     (funcall (intern (concat lang "-mode")))
 		     (comment-region (point) (progn (insert text) (point)))
 		     (comment-region (point) (progn (insert text) (point)))
-		     (org-babel-trim (buffer-string)))))
+		     (org-babel-trim (buffer-string))))
+	   (blocks () ;; return the info lists of all blocks in this buffer
+		   (let (infos)
+		     (save-restriction
+		       (widen)
+		       (org-babel-map-src-blocks nil
+			 (setq infos (cons (org-babel-get-src-block-info 'light)
+					   infos))))
+		     (reverse infos))))
       (with-temp-buffer
       (with-temp-buffer
         (insert body) (goto-char (point-min))
         (insert body) (goto-char (point-min))
         (setq index (point))
         (setq index (point))
@@ -1873,35 +1882,32 @@ block but are passed literally to the \"example-block\"."
 	       (if evaluate
 	       (if evaluate
 		   (let ((raw (org-babel-ref-resolve source-name)))
 		   (let ((raw (org-babel-ref-resolve source-name)))
 		     (if (stringp raw) raw (format "%S" raw)))
 		     (if (stringp raw) raw (format "%S" raw)))
-		 (or (nth 2 (assoc (intern source-name)
-				   org-babel-library-of-babel))
-		     (save-restriction
-		       (widen)
-		       (let ((point (org-babel-find-named-block
-				     source-name)))
-			 (if point
-			     (save-excursion
-			       (goto-char point)
-			       ;; possibly wrap body in comments
-			       (let* ((i (org-babel-get-src-block-info 'light))
-				      (body (org-babel-trim
-					     (org-babel-expand-noweb-references
-					      i))))
-				 (if comment
-				     ((lambda (cs) (concat (c-wrap (car cs)) "\n"
-						      body
-						      "\n" (c-wrap (cadr cs))))
-				      (org-babel-tangle-comment-links i))
-				   body)))
-			   ;; optionally raise an error if named
-			   ;; source-block doesn't exist
-			   (if (member lang org-babel-noweb-error-langs)
-			       (error "%s"
-				      (concat
+		 (or
+		  ;; retrieve from the library of babel
+		  (nth 2 (assoc (intern source-name)
+				org-babel-library-of-babel))
+		  ;; find the expansion of reference in this buffer
+		  (or (mapconcat
+		       (lambda (i)
+			 (when (string= source-name
+					(or (cdr (assoc :noweb-ref (nth 2 i)))
+					    (nth 4 i)))
+			   (let ((body (org-babel-expand-noweb-references i)))
+			     (if comment
+				 ((lambda (cs) (concat (c-wrap (car cs)) "\n"
+						  body "\n" (c-wrap (cadr cs))))
+				  (org-babel-tangle-comment-links i))
+			       body))))
+		       (or blocks-in-buffer
+			   (setq blocks-in-buffer (blocks)))
+		       "")
+		      ;; possibly raise an error if named block doesn't exist
+		      (if (member lang org-babel-noweb-error-langs)
+			  (error "%s" (concat
 				       "<<" source-name ">> "
 				       "<<" source-name ">> "
 				       "could not be resolved (see "
 				       "could not be resolved (see "
 				       "`org-babel-noweb-error-langs')"))
 				       "`org-babel-noweb-error-langs')"))
-			     ""))))))
+			""))))
 	       "[\n\r]") (concat "\n" prefix)))))
 	       "[\n\r]") (concat "\n" prefix)))))
         (nb-add (buffer-substring index (point-max)))))
         (nb-add (buffer-substring index (point-max)))))
     new-body))
     new-body))

+ 57 - 23
lisp/org-agenda.el

@@ -1759,11 +1759,11 @@ The following commands are available:
   (org-add-hook 'post-command-hook 'org-agenda-post-command-hook nil 'local)
   (org-add-hook 'post-command-hook 'org-agenda-post-command-hook nil 'local)
   (org-add-hook 'pre-command-hook 'org-unhighlight nil 'local)
   (org-add-hook 'pre-command-hook 'org-unhighlight nil 'local)
   ;; Make sure properties are removed when copying text
   ;; Make sure properties are removed when copying text
-  (when (boundp 'filter-buffer-substring-functions)
-    (org-set-local 'filter-buffer-substring-functions
+  (when (boundp 'buffer-substring-filters)
+    (org-set-local 'buffer-substring-filters
 		   (cons (lambda (x)
 		   (cons (lambda (x)
                            (set-text-properties 0 (length x) nil x) x)
                            (set-text-properties 0 (length x) nil x) x)
-			 filter-buffer-substring-functions)))
+			 buffer-substring-filters)))
   (unless org-agenda-keep-modes
   (unless org-agenda-keep-modes
     (setq org-agenda-follow-mode org-agenda-start-with-follow-mode
     (setq org-agenda-follow-mode org-agenda-start-with-follow-mode
 	  org-agenda-entry-text-mode org-agenda-start-with-entry-text-mode
 	  org-agenda-entry-text-mode org-agenda-start-with-entry-text-mode
@@ -4816,19 +4816,40 @@ This function is invoked if `org-agenda-todo-ignore-deadlines',
 	    (push txt ee)))))
 	    (push txt ee)))))
     (nreverse ee)))
     (nreverse ee)))
 
 
-(defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks)
+;; Calendar sanity: define some functions that are independent of
+;; `calendar-date-style'.
+;; Normally I would like to use ISO format when calling the diary functions,
+;; but to make sure we still have Emacs 22 compatibility we bind
+;; also `european-calendar-style' and use european format
+(defun org-anniversary (year month day &optional mark)
+  "Like `diary-anniversary', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european) (european-calendar-style t))
+     (diary-anniversary day month year mark))))
+(defun org-cyclic (N year month day &optional mark)
+  "Like `diary-cyclic', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)	(european-calendar-style t))
+     (diary-cyclic N day month year mark))))
+(defun org-block (Y1 M1 D1 Y2 M2 D2 &optional mark)
+  "Like `diary-block', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)	(european-calendar-style t))
+     (diary-block D1 M1 Y1 D2 M2 Y2 mark))))
+(defun org-date (year month day &optional mark)
+  "Like `diary-date', but with fixed (ISO) order of arguments."
+  (org-no-warnings
+   (let ((calendar-date-style 'european)	(european-calendar-style t))
+     (diary-date day month year mark))))
+
+;; Define the` org-class' function
+(defun org-class (y1 m1 d1 y2 m2 d2 dayname &rest skip-weeks)
   "Entry applies if date is between dates on DAYNAME, but skips SKIP-WEEKS.
   "Entry applies if date is between dates on DAYNAME, but skips SKIP-WEEKS.
-The order of the first 2 times 3 arguments depends on the variable
-`calendar-date-style' or, if that is not defined, on `european-calendar-style'.
-So for American calendars, give this as MONTH DAY YEAR, for European as
-DAY MONTH YEAR, and for ISO as YEAR MONTH DAY.
 DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
 DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
 is any number of ISO weeks in the block period for which the item should
 is any number of ISO weeks in the block period for which the item should
 be skipped."
 be skipped."
-  (let* ((date1 (calendar-absolute-from-gregorian
-		 (org-order-calendar-date-args m1 d1 y1)))
-	 (date2 (calendar-absolute-from-gregorian
-		 (org-order-calendar-date-args m2 d2 y2)))
+  (let* ((date1 (calendar-absolute-from-gregorian (list m1 d1 y1)))
+	 (date2 (calendar-absolute-from-gregorian (list m2 d2 y2)))
 	 (d (calendar-absolute-from-gregorian date)))
 	 (d (calendar-absolute-from-gregorian date)))
     (and
     (and
      (<= date1 d)
      (<= date1 d)
@@ -4840,6 +4861,28 @@ be skipped."
 	   (not (member (car (calendar-iso-from-absolute d)) skip-weeks))))
 	   (not (member (car (calendar-iso-from-absolute d)) skip-weeks))))
      entry)))
      entry)))
 
 
+(defun org-diary-class (m1 d1 y1 m2 d2 y2 dayname &rest skip-weeks)
+  "Like `org-class', but honor `calendar-date-style'.
+The order of the first 2 times 3 arguments depends on the variable
+`calendar-date-style' or, if that is not defined, on `european-calendar-style'.
+So for American calendars, give this as MONTH DAY YEAR, for European as
+DAY MONTH YEAR, and for ISO as YEAR MONTH DAY.
+DAYNAME is a number between 0 (Sunday) and 6 (Saturday).  SKIP-WEEKS
+is any number of ISO weeks in the block period for which the item should
+be skipped.
+
+This function is here only for backward compatibility and it is deprecated,
+please use `org-class' instead."
+  (let* ((date1 (calendar-absolute-from-gregorian
+		 (org-order-calendar-date-args m1 d1 y1)))
+	 (date2 (calendar-absolute-from-gregorian
+		 (org-order-calendar-date-args m2 d2 y2)))
+	 (d (calendar-absolute-from-gregorian date)))
+    (org-class
+     (nth 2 date1) (car date1) (nth 1 date1)
+     (nth 2 date2) (car date2) (nth 1 date2)
+     dayname skip-weeks)))
+
 (defalias 'org-get-closed 'org-agenda-get-progress)
 (defalias 'org-get-closed 'org-agenda-get-progress)
 (defun org-agenda-get-progress ()
 (defun org-agenda-get-progress ()
   "Return the logged TODO entries for agenda display."
   "Return the logged TODO entries for agenda display."
@@ -7768,17 +7811,8 @@ the resulting entry will not be shown.  When TEXT is empty, switch to
       (org-back-over-empty-lines)
       (org-back-over-empty-lines)
       (backward-char 1)
       (backward-char 1)
       (insert "\n")
       (insert "\n")
-      (require 'diary-lib)
-      (let ((calendar-date-display-form
-	     (if (if (boundp 'calendar-date-style)
-		     (eq calendar-date-style 'european)
-		   (with-no-warnings ;; european-calendar-style is obsolete as of version 23.1
-		     (org-bound-and-true-p european-calendar-style))) ; Emacs 22
-		 '(day " " month " " year)
-	       '(month " " day " " year))))
-
-	(insert (format "%%%%(diary-anniversary %s) %s"
-			(calendar-date-string d1 nil t) text))))
+      (insert (format "%%%%(org-anniversary %d %2d %2d) %s"
+		      (nth 2 d1) (car d1) (nth 1 d1) text)))
      ((eq type 'day)
      ((eq type 'day)
       (let ((org-prefix-has-time t)
       (let ((org-prefix-has-time t)
 	    (org-agenda-time-leading-zero t)
 	    (org-agenda-time-leading-zero t)

+ 4 - 4
lisp/org-indent.el

@@ -157,8 +157,8 @@ FIXME:  How to update when broken?"
       (org-set-local 'org-hide-leading-stars-before-indent-mode
       (org-set-local 'org-hide-leading-stars-before-indent-mode
 		     org-hide-leading-stars)
 		     org-hide-leading-stars)
       (org-set-local 'org-hide-leading-stars t))
       (org-set-local 'org-hide-leading-stars t))
-    (make-local-variable 'filter-buffer-substring-functions)
-    (add-to-list 'filter-buffer-substring-functions
+    (make-local-variable 'buffer-substring-filters)
+    (add-to-list 'buffer-substring-filters
 		 'org-indent-remove-properties-from-string)
 		 'org-indent-remove-properties-from-string)
     (org-add-hook 'org-after-demote-entry-hook
     (org-add-hook 'org-after-demote-entry-hook
 		  'org-indent-refresh-section nil 'local)
 		  'org-indent-refresh-section nil 'local)
@@ -177,9 +177,9 @@ FIXME:  How to update when broken?"
 	(when (boundp 'org-hide-leading-stars-before-indent-mode)
 	(when (boundp 'org-hide-leading-stars-before-indent-mode)
 	  (org-set-local 'org-hide-leading-stars
 	  (org-set-local 'org-hide-leading-stars
 			 org-hide-leading-stars-before-indent-mode))
 			 org-hide-leading-stars-before-indent-mode))
-	(setq filter-buffer-substring-functions
+	(setq buffer-substring-filters
 	      (delq 'org-indent-remove-properties-from-string
 	      (delq 'org-indent-remove-properties-from-string
-		    filter-buffer-substring-functions))
+		    buffer-substring-filters))
 	(remove-hook 'org-after-promote-entry-hook
 	(remove-hook 'org-after-promote-entry-hook
 		     'org-indent-refresh-section 'local)
 		     'org-indent-refresh-section 'local)
 	(remove-hook 'org-after-demote-entry-hook
 	(remove-hook 'org-after-demote-entry-hook

+ 28 - 0
testing/examples/babel.org

@@ -174,3 +174,31 @@
 #+begin_src emacs-lisp :var lst=a-list :results list
 #+begin_src emacs-lisp :var lst=a-list :results list
   (reverse lst)
   (reverse lst)
 #+end_src
 #+end_src
+* using the =:noweb-ref= header argument
+  :PROPERTIES:
+  :ID:       54d68d4b-1544-4745-85ab-4f03b3cbd8a0
+  :END:
+
+#+begin_src sh :tangle yes :noweb yes :shebang #!/bin/sh
+  <<fullest-disk>>
+#+end_src
+
+** query all mounted disks
+#+begin_src sh :noweb-ref fullest-disk
+  df \
+#+end_src
+
+** strip the header row
+#+begin_src sh :noweb-ref fullest-disk
+  |sed '1d' \
+#+end_src
+
+** sort by the percent full
+#+begin_src sh :noweb-ref fullest-disk
+  |awk '{print $5 " " $6}'|sort -n |tail -1 \
+#+end_src
+
+** extract the mount point
+#+begin_src sh :noweb-ref fullest-disk
+  |awk '{print $2}'
+#+end_src

+ 17 - 0
testing/lisp/test-ob-tangle.el

@@ -49,9 +49,26 @@
   "Don't add IDs to headings without tangling code blocks."
   "Don't add IDs to headings without tangling code blocks."
   (org-test-at-id "ef06fd7f-012b-4fde-87a2-2ae91504ea7e"
   (org-test-at-id "ef06fd7f-012b-4fde-87a2-2ae91504ea7e"
     (org-babel-next-src-block)
     (org-babel-next-src-block)
+    (org-narrow-to-subtree)
     (org-babel-tangle)
     (org-babel-tangle)
     (should (null (org-id-get)))))
     (should (null (org-id-get)))))
 
 
+(ert-deftest ob-tangle/continued-code-blocks-w-noweb-ref ()
+  "Test that the :noweb-ref header argument is used correctly."
+  (org-test-at-id "54d68d4b-1544-4745-85ab-4f03b3cbd8a0"
+    (let ((tangled "df \\
+|sed '1d' \\
+|awk '{print $5 \" \" $6}'|sort -n |tail -1 \\
+|awk '{print $2}'
+"))
+      (org-narrow-to-subtree)
+      (org-babel-tangle)
+      (with-temp-buffer
+	(insert-file-contents "babel.sh")
+	(goto-char (point-min))
+	(should (re-search-forward (regexp-quote tangled) nil t)))
+      (delete-file "babel.sh"))))
+
 (provide 'test-ob-tangle)
 (provide 'test-ob-tangle)
 
 
 ;;; test-ob-tangle.el ends here
 ;;; test-ob-tangle.el ends here