Please, wait a few seconds

Latex footnotes, citations, etc. in IPython Notebook

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc in risus elit. Vestibulum lacus dolor, egestas id feugiat a, mollis sit amet lectus. Nullam elementum nulla sit amet purus rhoncus porttitor. Mauris pulvinar enim at dui rutrum scelerisque. Donec tempus risus et nibh porta mollis. Donec sit amet orci ligula\footnote{Nullam non risus et arcu posuere malesuada. Nullam suscipit pellentesque nibh vel malesuada}.

Cras vestibulum tempus urna, vel suscipit erat sagittis sit amet. Curabitur id lacus quam. Aliquam erat volutpat. Nulla id est ipsum, quis dictum lacus. In nec ante ligula. Praesent elit ipsum, semper quis commodo id, interdum tempor turpis. Donec eu sapien tellus. Sed id ligula libero. In hac habitasse platea dictumst\footnote{Quisque odio tortor, venenatis a placerat a, pellentesque sit amet risus. Maecenas fermentum turpis vitae odio ultricies in tempus tellus facilisis. Fusce nec sapien quam. Maecenas eget elit a orci egestas convallis. Aliquam erat volutpat.}.

Quisque aliquet elementum felis, commodo vestibulum massa porta a. Pellentesque eget erat a felis euismod feugiat non vitae turpis\footnote{Vivamus fermentum libero id massa scelerisque porta. Nam et mi leo. Suspendisse potenti. Integer placerat ipsum vel dolor lacinia et eleifend turpis scelerisque. Aenean vel eros odio.}. Quisque hendrerit ante tristique mauris tempor rutrum. Vestibulum malesuada eleifend dolor quis tristique. Nullam id elit sed neque commodo pharetra ut nec velit.

In [1]:
from IPython.core.display import publish_html
In [7]:
publish_html('<scrip src="http://code.jquery.com/jquery-1.8.3.min.js"></scrip>')

I am doing it with setInterval, mostly because I din't care to find out how to detect if a cell was rendered or not.

In [2]:
def setInterval(js, time):
    publish_html('''<script>
    window.setInterval(function(){{
            {0}
        }}, {1});
    </script>
    '''.format(js, time))
In [8]:
css='''
.text_cell, .code_cell, .text_cell_render{
  max-width:810px;
}
.text_cell_render
{
  position:relative!important;
}
aside
{
  background:rgba(255,255,80,0.4);
  border:1px solid rgba(255,210,80,0.8);
  border-radius:4px;
  border-top:5px;
  display:block;
  font-size:.85em;
  left:845px;
  padding:1em;
  position:absolute;
  top:0px;
  text-align:left;
  width:150px;
  z-index:5;
  -moz-box-shadow: 2px 2px 5px #CCC;
  -webkit-box-shadow: 2px 2px 5px #CCC;
  box-shadow: 2px 2px 5px #CCC;
}
.footnote
{
  color:red;
  font-size:.7em;
  position:relative;
  top:-.7em;
  text-transform: uppercase;
}

.footnote.big
{
  font-size:1em;
  top:0;
  text-transform: uppercase;
}
'''
publish_html('<style>'+css+'</style>')

This is the base js for extracting footnotes, a similar function can be easily constructed for arbitrary \tag{}\footnote{I use similar functions to in my own work} and apply any styling to it.

Moreover, this can be easily extended to cater for \cite{} as well if the notebook publishes a bibliography object.

In [17]:
js='''
var jCounter=0;
$('.text_cell_render p, .text_cell_render li').each(function(){
    var x=$(this).html().match(/[\s]*\\\\footnote\{(.|[\s-]|<[\/][\w]*>)*?\}/gi);
    if( x!=null ){  
        
        for(var i=0; i<x.length; ++i){
            try{
                ++jCounter;
                $(this).html($(this).html().replace(x[i],'<span class="footnote">'
                                                    +jCounter
                                                    +'</span><aside><span class="footnote big">'
                                                    +jCounter
                                                    +'</span>'
                                                    +' '
                                                    +x[i].substring(10+x[i].length-$.trim(x[i]).length, x[i].length-1)
                                                    +'</aside>'));
            }
            catch(err){
                continue;
            }
            
        }
    }  
});
'''
In [18]:
#This I found somewhere on the Internet and I think I changed some little things
jsOffsets='''
try{
    var orgOffset=[]
    var elements=[]
    var offsets=[]
    $('aside').each(function(){
        orgOffset.push($(this).css('top'));
    });
    $('aside').css('top',0)
    window.lastOffset=$('aside').first().offset()['top'];
    $('aside').each(function(i){
        curOffset=$(this).offset()['top'];
        shiftOffset=0;
        while( curOffset+shiftOffset<window.lastOffset + 5){
            ++shiftOffset;
        }
    
        window.lastOffset=curOffset+shiftOffset+$(this).outerHeight();
            elements.push($(this));
            offsets.push(shiftOffset);
            $(this).css('top', orgOffset[i]);
    });
    for(i=0; i<offsets.length; i++){
        if( offsets[i]!=orgOffset[i]){
            elements[i].animate(
                {
                top: offsets[i]
                },
                'slow');
        }
    }
}
catch(err){
    console.log(err);
}
'''
In [19]:
setInterval(js+jsOffsets, 10000)

You can also use it to autosave the notebook...

In []:
autosaveJs='''
IPython.notebook.save_notebook();
'''
setInterval(autosaveJs, 10000)
Back to top