5

I am trying to replace Microsoft Word(shudder) for this specific process. The process is not specific for email or traditional Mail but similar. The process is that I have a template file with variables that I pull from a spreadsheet. I'm able to "page" through the variables. I'm trying to replicate this in emacs. After searching I have found some cases of people accomplishing this but no details as to how. Thanks.

I'm going to try to explain further as requested. I need a template document that has variables that change per page like a mail merge(https://en.wikipedia.org/wiki/Mail_merge). My use case is not to print these so that is not needed. This is actually for automating the creation of 100's of router configs. Thanks again for all the replies.

Example:


hostname hostname-variable

!

username username-variable password 0 password-variable

!

no service pad

service timestamps debug datetime msec

And so on...


In Microsoft word you reference a excel spreadsheet for the variables. But I would be fine to reference the data in other ways. CSV, table, etc.

| Hostname-variable |username-variable | password-variable |
|-------------------+------------------+-------------------|
| Hostname1         |Username1         | password1         |
| Hostname2         |Username2         | password2         |
| Hostname3         |Username3         | password3         |
|-------------------+------------------+-------------------|

"Page 1" would look like this:


hostname Hostname1

!

username Username1 password 0 password1

!

no service pad

service timestamps debug datetime msec

And so on...


"Page 2" would look like this


hostname Hostname2

!

username Username2 password 0 password2

!

no service pad

service timestamps debug datetime msec

And so on...


"Page 3" would look like this


hostname Hostname3

!

username Username3 password 0 password3

!

no service pad

service timestamps debug datetime msec

And so on...


  • You will need to provide a sample data structure within the question itself, and explain specifically what it is that you are trying to accomplish. If you are hoping Emacs can print multiple envelopes or label-size pages based on a database of addresses (without much work), then you are likely mistaken. It is possible to create envelopes with LaTeX, but creating a mail merge and printing multiple envelopes or labels in a row will take some work and require precise specifications. The data structure will likely need to be a flat text file -- e.g., rows with delimiters -- not Excel. – lawlist Nov 28 '15 at 4:45
  • If your spreadsheet program can export data as some text format (eg CSV), you could use a UNIX patch utility to do this. You could use Emacs as an interface to it (there is a diff-mode which can highlight the changes and ediff program which can allow you to actually merge multiple files). However, typically the "mail merge" refers to the kind of merge that happens in certain version control systems (in particular Git), when changes are submitted via emails and follow some specific format, so you may want to clarify the relation to that later case. – wvxvw Nov 28 '15 at 13:23
  • If you like, I can modify my answer to generate individual files too. Depending on your requirements and infrastructure, it may also be possible to adjust the template connect to each router and do the configuration and then export the settings and results as documentation. Hope that helped. – Melioratus Nov 29 '15 at 22:51
  • Thank you to everyone for your help. @Melioratus I like what you done here. This really set me on the right track. If it is not too much trouble, how would you generate the individual files? Would that be in the Ruby code? – High-fi Nov 30 '15 at 16:38
  • The easiest way I've found is to modify the template to generate code blocks with a :tangle header with in a :results drawer. Then use C-c C-v t to tangle all the code blocks into separate files. I'll append an example of the technique to my answer. – Melioratus Dec 1 '15 at 0:45
4

Try this

Create a Named Table

#+NAME: my-data
| Hostname-variable |username-variable | password-variable |
|-------------------+------------------+-------------------|
| Hostname1         |Username1         | password1         |
| Hostname2         |Username2         | password2         |
| Hostname3         |Username3         | password3         |

Create Template Code Block, e.g. ruby

Note: For this example, I chose ruby but ruby is not required.

I encourage you to use your favorite language to write the template.

#+NAME: simple-template-ruby
#+BEGIN_SRC ruby :var data=my-data() :results replace   
  data.map{|d| 
  template = <<-MYFORM
    hostname #{d[0]}

    !

    username #{d[1]} password 0 #{d[2]}

    !

    no service pad

    service timestamps debug datetime msec


  MYFORM

  template

  }.join("\n")
#+END_SRC

Execute the Code Block using C-c C-C inside the code block or on inline #+CALL:.

#+NAME: Mail-Merge-Results
#+CALL: simple-template-ruby()

Below are the Mail Merge Results:

#+RESULTS: Mail-Merge-Results
hostname Hostname1

!

username Username1 password 0 password1

!

no service pad

service timestamps debug datetime msec



hostname Hostname2

!

username Username2 password 0 password2

!

no service pad

service timestamps debug datetime msec



hostname Hostname3

!

username Username3 password 0 password3

!

no service pad

service timestamps debug datetime msec

This code was tested using

GNU Emacs 24.4.1 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343.14)
 of 2014-12-25

org-mode version: 8.3.1

Below are the additional steps required to generate separate files, e.g. Hostname1.txt, Hostname2.txt and Hostname3.txt

Add Escaped Code Block to Template

  • Notice commas , are used to escape the org-mode syntax inside the template

    ,#+begin_src and ,#+end_src

  • Note that sh is used in this example but this could be any configured language, e.g. ruby

  • Prevent accidental execution by adding :eval never to escaped code block.

  • Set file name using :tangle #{d[0]}.txt

Below is the updated code block

#+NAME: tangled-template-ruby
#+BEGIN_SRC ruby :var data=my-data() :results replace   
  data.map{|d| 
  template = <<-MYFORM

  ,#+begin_src sh :eval never :tangle #{d[0]}.txt 
    hostname #{d[0]}

    !

    username #{d[1]} password 0 #{d[2]}

    !

    no service pad

    service timestamps debug datetime msec
  ,#+end_src

  MYFORM

  template

  }.join("\n")
#+END_SRC

Add :results drawer replace headers to inline#+CALL: statement

#+NAME: Mail-Merge-Results-into-Files
#+CALL: tangled-template-ruby() :results drawer replace 

Use C-c C-c on inline#+CALL: statement to generate results inside a drawer

#+RESULTS: Mail-Merge-Results-into-Files
:RESULTS:

#+begin_src sh :eval never :tangle Hostname1.txt 
  hostname Hostname1

  !

  username Username1 password 0 password1

  !

  no service pad

  service timestamps debug datetime msec
#+end_src



#+begin_src sh :eval never :tangle Hostname2.txt 
  hostname Hostname2

  !

  username Username2 password 0 password2

  !

  no service pad

  service timestamps debug datetime msec
#+end_src



#+begin_src sh :eval never :tangle Hostname3.txt 
  hostname Hostname3

  !

  username Username3 password 0 password3

  !

  no service pad

  service timestamps debug datetime msec
#+end_src

:END:

Use C-c C-v t to tangle the new code blocks into the separate files

You should see a message similar too this
Tangled 3 code blocks from your-file.org

Additional code was tested using

GNU Emacs 24.4.1 (x86_64-unknown-cygwin)
 of 2014-11-14

org-mode version: 8.2.10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.