# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # =========================================================================== """ MathIdevice: just has a block of text """ import logging from exe.engine.idevice import Idevice from exe.engine.field import MathField log = logging.getLogger(__name__) from exe.engine.path import Path from exe.engine.freetextidevice import FreeTextIdevice from exe import globals as G import os # =========================================================================== class MathIdevice(Idevice): """ MathIdevice: just has a block of text """ persistenceVersion = 1 def __init__(self, instruc="", latex=""): Idevice.__init__(self, x_(u"Maths"), x_(u"University of Auckland"), x_("""The mathematical language LATEX has been used to enable your to insert mathematical formula into your content. It does this by translating LATEX into an image which is then displayed within your eXe content. We would recommend that you use the Free Text iDevice to provide explanatory notes and learning instruction around this graphic."""), "", "") self.emphasis = Idevice.NoEmphasis self.content = MathField(x_(u"Maths"), x_(u"""You can use the toolbar or enter latex manually into the textarea. """)) self.content.idevice = self def getResourcesField(self, this_resource): """ implement the specific resource finding mechanism for this iDevice: """ # be warned that before upgrading, this iDevice field could not exist: if hasattr(self, 'content') and hasattr(self.content, 'gifResource'): if this_resource == self.content.gifResource: return self.content return None def getRichTextFields(self): """ Like getResourcesField(), a general helper to allow nodes to search through all of their fields without having to know the specifics of each iDevice type. """ # Math iDevice has no rich-text fields: return [] def upgradeToVersion1(self): """ Converting MathsIdevice -> FreeTextIdevice, now that FreeText can hold embeddded images. BUT - due to the inconsistent loading of the objects via unpickling, since the resources aren't necessarily properly loaded and upgraded, NOR is the package necessarily, as it might not even have a list of resources yet, all of this conversion code must be done in an afterUpgradeHandler """ G.application.afterUpgradeHandlers.append(self.convertToFreeText) def convertToFreeText(self): """ Actually do the Converting of MathsIdevice -> FreeTextIdevice, now that FreeText can hold embeddded images. """ new_content = "" # ensure that an image resource still exists on this ImageWithText, # before trying to add it into the FreeText idevice. # Why? corrupt packages have been seen missing resources... # (usually in with extra package objects as well, probably # from old code doing faulty Extracts, or somesuch nonesense) imageResource_exists = False if not self.content.gifResource is None: if os.path.exists(self.content.gifResource.path) and \ os.path.isfile(self.content.gifResource.path): imageResource_exists = True else: log.warn("Couldn't find Maths image when upgrading "\ + self.content.gifResource.storageName) if imageResource_exists: new_content += " including resources path, # but still need the actual image resource: if imageResource_exists: # Not sure why this can't be imported up top, but it gives # ImportError: cannot import name GalleryImages, # so here it be: from exe.engine.galleryidevice import GalleryImage full_image_path = self.content.gifResource.path # with empty caption: new_GalleryImage = GalleryImage(replacementIdev.content, \ '', full_image_path, mkThumbnail=False) # and.... write the latex_source out into the preview_math_srcfile # such that it can then be passed into the compile command. # Using the desired name (image.gif.tex), write it into tempWebDir: webDir = Path(G.application.tempWebDir) source_tex_name = self.content.gifResource.storageName+".tex" math_path = webDir.joinpath(source_tex_name) math_filename_str = math_path.abspath().encode('utf-8') log.debug("convertToFreeText: writing LaTeX source into \'" \ + math_filename_str + "\'.") math_file = open(math_filename_str, 'wb') # do we need to append a \n here?: math_file.write(self.content.latex) math_file.flush() math_file.close() # finally, creating a resource for the latex_source as well: new_GalleryLatex = GalleryImage(replacementIdev.content, \ '', math_filename_str, mkThumbnail=False) new_GalleryLatexResource = new_GalleryLatex._imageResource mathsrc_resource_path = new_GalleryLatexResource._storageName # and re-concatenate from the global resources name, # to build the webUrl to the resource: mathsrc_resource_url = new_GalleryLatex.resourcesUrl \ + mathsrc_resource_path # AND compare with the newly built resource_url from above, # to ensure that we've got what we had expected, jah! if (mathsrc_resource_url != math_resource_url): log.warn('The math source was resource-ified differently ' \ + 'than expected, to: ' + mathsrc_resource_url \ + '; the source will need to be recreated.') # right. we COULD go ahead and change the exe_math_latex # attribute to point to the actual mathsrc_resource_url, # EXCEPT that the entire exemath plugin is currently built # with the idea that the source .tex file will always be named # as the mathimage.gif.tex, and this exe_math_latex tag # is really just letting the rest of the world know that # there IS corresponding source expected there. # If exemath is to ever change and use the actual contents # of this exe_math_latex tag (rather than just appended .tex), # then this could be revisited here. else: log.debug('math source was resource-ified properly to: ' \ + mathsrc_resource_url) # and move the new idevice up to the position following this node! while ( self.parentNode.idevices.index(replacementIdev) \ > ( (self.parentNode.idevices.index(self) + 1))): replacementIdev.movePrev() # finally: delete THIS idevice itself, deleting it from the node self.delete() # =========================================================================== # ===========================================================================