Comments (1)
I was able to implement this using configuration only in my branch live-2.0 which contains processor registration and a template DOM, only the DOM bit is actually needed. This doesn't do all that I talk about above since it relies on HTML to insert the references instead of allowing the option to insert a reference using regular insertion via a merge field in the document itself.
Code used is below:
module Sablon
# Adding custom handler to DOM
module DOM
# Manages footnotes in the document
class Footnotes < FileHandler
#
# extends the Model class so it now has an "add_footnote" method.
def self.extend_model(model_klass)
super do
#
# adds a footnote to the file and returns the id
define_method(:add_footnote) do |env, content|
@dom['word/footnotes.xml'].add_footnote(env, content)
end
end
end
# sets up the class to add new footnotes
def initialize(xml_node)
super
#
@footnotes = xml_node.root
@max_id = max_attribute_value(@footnotes, '//w:footnote', 'w:id')
end
# Add the footnote and return the id number used
def add_footnote(env, content)
# add the node to the document
current_id = next_id
new_node = @footnotes.add_child(footnote_tag(current_id))
#
# append the content to the footnote node
paragraph = new_node.xpath('./w:p').last
display_node = paragraph.at_xpath('.//w:t')
content.append_to(paragraph, display_node, env)
#
# add in a reference tag
new_node.xpath('.//w:r').first.add_previous_sibling(footnote_ref_tag)
#
current_id
end
private
# Increments the ID and returns it
def next_id
@max_id += 1
end
# This generates the proper footnote tag by injecting the content
# into it.
def footnote_tag(id)
<<-XML.gsub(/^\s*|\n/, '')
<w:footnote w:id="#{id}">
<w:p>
<w:pPr>
<w:pStyle w:val="FootnoteText"/>
</w:pPr>
<w:r>
<w:t xml:space="preserve">Replace Me!</w:t>
</w:r>
</w:p>
</w:footnote>
XML
end
# generates the reference tag which shows the number in the
# bottom of the page by the footnote.
def footnote_ref_tag
<<-XML.gsub(/^\s*|\n/, '')
<w:r>
<w:rPr>
<w:rStyle w:val="FootnoteReference"/>
</w:rPr>
<w:footnoteRef/>
</w:r>
XML
end
end
register_dom_handler(%r{word/footnotes.xml}, Sablon::DOM::Footnotes)
end
# Locally added content types
module Content
# Allows footnotes to be properly inserted into the document
class Footnote
include Sablon::Content
def self.id
:footnote
end
def self.wraps?(*)
false
end
def initialize(options)
type_id = options['content_type'].to_sym
@content = Content.make(type_id, options['content'])
end
def append_to(*args)
@content.append_to(*args)
end
end
#
register Sablon::Content::Footnote
end
# Locally added HTML AST classes
class HTMLConverter
# inserts a footnote refrence into the document
class FootnoteReference < Run
def initialize(env, node, properties)
@properties = NodeProperties.run(properties)
#
# only works if footnotes aren't nested inside another hash
name = node['placeholder']
footnote_content = env.context[name]
@footnote_id = env.document.add_footnote(env, footnote_content)
end
def inspect
"<FootnoteReference{#{@properties.inspect}}: Id:#{@footnote_id}>"
end
private
def children_to_docx
"<w:footnoteReference w:id=\"#{@footnote_id}\"/>"
end
end
end
end
from sablon.
Related Issues (16)
- Use a basic WordML xml file as partial
- Add processing of endnotes and footnotes HOT 3
- Implement a way to add footnotes, table and figure references HOT 2
- Implement MS word comments in HTML?
- Implement equations
- Make Sablon use live XML instead of strings until files are written HOT 2
- Refactor template.rb so processors can be "registered" HOT 2
- Implement a simple DOM to use with a template HOT 2
- Use a regular docx file as a partial, only for simple text HOT 2
- Allow headers and footer text content to be filled by a partial
- Allow images to be imported with a partial HOT 1
- Implement code coverage HOT 1
- Change Numbering class from a singleton into being registered on the Context object
- Current issues when using partials HOT 1
- Expand HTML processing capabilities HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sablon.