2

I'm building a web application using the literate programming style. At least trying to.

I wanted to "hit the ground running", so I decided "make a copy" of one of the many "starter apps"

https://github.com/RailsApps/rails-bootstrap

So before I have written a single line of code, I have a directory structure for the application (app/ public/ tmp/ etc), and tons of boilerplate code.

The first piece of code I wrote in my org file is this

#+begin_src ruby
after_create :create_braintree_customer

def create_braintree_customer
  Braintree.api_key = "bk-54cfa45"
  self.id = Braintree::Customer.create.id
  self.save
end
#+end_src

Now when "tangling", this method should go here:

$ cat ~/project/app/models/user.rb 
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  <<<<<<<< my code block should come here >>>>>>>>>>>>

end

Is this possible with the literate programming tools available with emacs?

What I tried: Read some examples at https://github.com/limist/literate-programming-examples but the tangling there generates whole files. I want to "embed" my stuff in to "template generated" stuff of the MVC application.

american-ninja-warrior
  • 3,773
  • 2
  • 21
  • 40
  • There's this suggestion which comes close to an answer but imho not the correct answer: https://emacs.stackexchange.com/a/28108 – american-ninja-warrior Jan 17 '18 at 13:01
  • saw this, close but no sugar https://raw.githubusercontent.com/IronBrushTattoo/cj_rails/master/README.org – american-ninja-warrior Jan 17 '18 at 13:12
  • Org has `radio tables` and `radio lists` - the ability to do what you want for tables and lists. Perhaps the code there offers a way to implement `radio babels` which do what you want. – mankoff Jan 17 '18 at 16:34

1 Answers1

1

There are two options you could use, but I imagine that none are exactly what you want:

1) Create derived classes from the template classes

#+begin_src ruby :tangle ./app/models/appuser.rb      
class AppUser < User
  after_create :create_braintree_customer

  def create_braintree_customer
    Braintree.api_key = "bk-54cfa45"
    self.id = Braintree::Customer.create.id
    self.save
  end

end
#+end_src

2) Import the code of the files you are modifying into the org-file

#+begin_src ruby :tangle ./app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  after_create :create_braintree_customer

  def create_braintree_customer
    Braintree.api_key = "bk-54cfa45"
    self.id = Braintree::Customer.create.id
    self.save
  end

end
#+end_src

However, I think that it would be better to separate the template generated code from the tangled code of your application anyway.

If you really want to surgically insert the tangled blocks, you could do it with some kind of ad-hoc templating, such as inserting tags like {{{BLOCK_NAME}}} in the template files and then running a script to search and replace the tags with the tangled blocks from the org-mode file. That seems to me to be cludgy and fragile. I will always choose a simple and easy solution over a clever but complicated one.

Martín
  • 416
  • 2
  • 8