Exporting: Improving PDF exportation via XeLaTeX for unicode support. Still some leftovers proper cleaning needs to be debugged.

This commit is contained in:
Offray Vladimir Luna Cárdenas 2016-04-06 10:00:57 +00:00
parent d08470823a
commit 47a9e4bf8f
3 changed files with 198 additions and 47 deletions

View File

@ -11,7 +11,8 @@ Class {
'downloadUrl', 'downloadUrl',
'description', 'description',
'sha1', 'sha1',
'md5' 'md5',
'binaryLocation'
], ],
#category : #'Grafoscopio-Model' #category : #'Grafoscopio-Model'
} }
@ -106,3 +107,89 @@ ExternalApp class >> isSQLite32BitsInstalled [
^ (FileSystem disk workingDirectory parent / 'bin' / 'libsqlite3.so') asFileReference exists ^ (FileSystem disk workingDirectory parent / 'bin' / 'libsqlite3.so') asFileReference exists
] ]
{ #category : #configuration }
ExternalApp class >> pandoc [
"I define where the pandoc external app is located"
| app |
app := ExternalApp new
name: 'pandoc';
url: 'http://pandoc.org';
description: 'Pandoc is a free and open-source software document converter, widely used as a writing tool (especially by scholars) and as a basis for publishing workflows. It was originally created by John MacFarlane, a philosophy professor at the University of California, Berkeley. (from https://en.wikipedia.org/wiki/Pandoc)'.
app binaryLocation: '/usr/bin/pandoc' asFileReference.
^ app
]
{ #category : #accessing }
ExternalApp >> binaryLocation [
^ binaryLocation
]
{ #category : #accessing }
ExternalApp >> binaryLocation: anObject [
binaryLocation := anObject
]
{ #category : #accessing }
ExternalApp >> description [
^ description
]
{ #category : #accessing }
ExternalApp >> description: anObject [
description := anObject
]
{ #category : #accessing }
ExternalApp >> downloadUrl [
^ downloadUrl
]
{ #category : #accessing }
ExternalApp >> downloadUrl: anObject [
downloadUrl := anObject
]
{ #category : #accessing }
ExternalApp >> md5 [
^ md5
]
{ #category : #accessing }
ExternalApp >> md5: anObject [
md5 := anObject
]
{ #category : #accessing }
ExternalApp >> name [
^ name
]
{ #category : #accessing }
ExternalApp >> name: anObject [
name := anObject
]
{ #category : #accessing }
ExternalApp >> sha1 [
^ sha1
]
{ #category : #accessing }
ExternalApp >> sha1: anObject [
sha1 := anObject
]
{ #category : #accessing }
ExternalApp >> url [
^ url
]
{ #category : #accessing }
ExternalApp >> url: anObject [
url := anObject
]

View File

@ -16,17 +16,11 @@ Class {
'mainTree', 'mainTree',
'tagsAvailable', 'tagsAvailable',
'cacheNode', 'cacheNode',
'workingFile', 'workingFile'
'localRepository',
'remoteRepository',
'repositoryUser',
'repositoryPassword'
], ],
#classVars : [ #classVars : [
'dockingBar', 'dockingBar',
'draftsLocation', 'draftsLocation',
'fossil',
'pandoc',
'recentTrees' 'recentTrees'
], ],
#classInstVars : [ #classInstVars : [
@ -699,23 +693,47 @@ GrafoscopioBrowser >> customKeys [
{ #category : #persistence } { #category : #persistence }
GrafoscopioBrowser >> exportAsHtml [ GrafoscopioBrowser >> exportAsHtml [
"Exports the current tree to HTML, using the same name but different extension (.html)" "I exports the current tree to HTML, using the same name but different extension (.html).
IMPORTANT: Pandoc must be installed in your system. In the future Grafoscopio will provide"
| markdownFileLocation htmlFileLocation | | markdownFileLocation htmlFileLocation |
markdownFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.markdown'. markdownFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.markdown'.
htmlFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.html'. htmlFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.html'.
pandoc notNil ExternalApp pandoc notNil
ifTrue:[ ifTrue:[
(Smalltalk platform name = 'unix') | (Smalltalk platform name = 'Mac OS') (Smalltalk platform name = 'unix') | (Smalltalk platform name = 'Mac OS')
ifTrue: [ ifTrue: [
OSProcess command: 'exec ', pandoc, ' ', markdownFileLocation , ' --standalone -o ' , htmlFileLocation. OSProcess command: 'pandoc ', ' ', markdownFileLocation , ' --standalone -o ' , htmlFileLocation.
OSProcess command: 'exec echo "exportando como html"'. OSProcess command: 'exec echo "exportando como html"'.
self inform: 'Archivo exportado como html en: ', htmlFileLocation]. self inform: 'Archivo exportado como html en: ', htmlFileLocation].
Smalltalk platform name = 'Win32' Smalltalk platform name = 'Win32'
ifTrue: [ OSProcess command: pandoc, ' ', markdownFileLocation , ' --standalone -o ' , htmlFileLocation ]] ifTrue: [ OSProcess command: 'pandoc ', markdownFileLocation , ' --standalone -o ' , htmlFileLocation ]]
ifFalse: [GrafoscopioBrowser configureSettings]. ifFalse: [GrafoscopioBrowser configureSettings].
]
self customKeys. { #category : #persistence }
GrafoscopioBrowser >> exportAsLatex [
"I Export the current tree to LaTeX, using the same name but different extension (.tex).
IMPORTANT: The user needs to have TeX installed with minted support and pygments for syntax highlighting.
More details at: http://ctan.dcc.uchile.cl/macros/latex/contrib/minted/minted.pdf"
| markdownFileLocation latexFileLocation fileName |
fileName := workingFile basenameWithoutExtension.
markdownFileLocation := ((workingFile parent) / fileName) fullName, '.markdown'.
latexFileLocation := ((workingFile parent) / fileName) fullName, '.tex'.
ExternalApp pandoc binaryLocation exists
ifFalse: [ExternalApp configurePandoc]
ifTrue:[
OSProcess command:
'pandoc ', markdownFileLocation,
' -V documentclass:article -V geometry:margin=2cm --standalone -o ' ,
fileName, '.tex'.
"Moving the pdf output to the expected location"
latexFileLocation asFileReference exists ifTrue: [latexFileLocation asFileReference ensureDelete ].
(FileLocator imageDirectory parent / (fileName, '.tex'))
moveTo: latexFileLocation asFileReference.
"Cleaning left overs"
(FileLocator imageDirectory parent / (fileName, '.tex')) ensureDelete.
self inform: 'Archivo exportado como latex en: ', latexFileLocation
]
] ]
{ #category : #persistence } { #category : #persistence }
@ -728,22 +746,28 @@ GrafoscopioBrowser >> exportAsMarkdown: aTree on: locator [
GrafoscopioBrowser >> exportAsPdf [ GrafoscopioBrowser >> exportAsPdf [
"Exports the current tree to HTML, using the same name but different extension (.pdf). "Exports the current tree to HTML, using the same name but different extension (.pdf).
IMPORTANT: The user needs to have installed TeX to create the pdf." IMPORTANT: The user needs to have installed TeX to create the pdf."
| markdownFileLocation pdfFileLocation | | latexFileLocation pdfFileLocation fileName |
markdownFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.markdown'. fileName := workingFile basenameWithoutExtension.
pdfFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.pdf'. self exportAsLatex.
pandoc notNil latexFileLocation := ((workingFile parent) / fileName) fullName, '.tex'.
pdfFileLocation := ((workingFile parent) / fileName) fullName, '.pdf'.
'/usr/bin/xelatex' asFileReference exists
ifTrue: [ ifTrue: [
Smalltalk platform name = 'unix' "Generating the pdf"
ifTrue: [ OSProcess command: 'xelatex --shell-escape ', latexFileLocation.
OSProcess command: 'exec ', pandoc, ' ', markdownFileLocation , ' -o ' , pdfFileLocation. "Moving the pdf output to the expected location"
OSProcess command: 'exec echo "exportando como pdf"'. pdfFileLocation asFileReference exists ifTrue: [pdfFileLocation asFileReference ensureDelete ].
self inform: 'Archivo exportado como pdf en: ', pdfFileLocation.]. (FileLocator imageDirectory parent / (fileName, '.pdf'))
Smalltalk platform name = 'Win32' moveTo: pdfFileLocation asFileReference.
ifTrue: [ OSProcess command: pandoc, ' ', markdownFileLocation , ' -o ' , pdfFileLocation ]] "Cleaning left overs"
ifFalse: [ExternalApp configurePandoc ]. #('.aux' '.out' '.log') do: [ :fileExension |
(FileLocator imageDirectory parent asFileReference / (fileName, fileExension)) ensureDelete].
self customKeys. (FileLocator imageDirectory parent asFileReference / ('_minted-', fileName)) deleteAll.
self inform: 'Archivo exportado como pdf en: ', pdfFileLocation]
ifFalse: [
self inform:
'Necesita instalar XeLaTeX/TeX más información en:', String cr,'
http://xetex.sourceforge.net/' ].
] ]
{ #category : #persistence } { #category : #persistence }
@ -1122,7 +1146,8 @@ GrafoscopioBrowser >> treeOn: constructor [
"For trees" "For trees"
act: [self saveToFileUI] entitled: 'Guardar como ...' categorized: 'Arbol'; act: [self saveToFileUI] entitled: 'Guardar como ...' categorized: 'Arbol';
act: [self saveWorkingTree; exportAsHtml] entitled: 'Exportar como HTML' categorized: 'Arbol'; act: [self saveWorkingTree; exportAsHtml] entitled: 'Exportar como HTML' categorized: 'Arbol';
act: [self saveWorkingTree; exportAsPdf] entitled: 'Exportar como PDF (requiere LaTeX)' categorized: 'Arbol'; act: [self saveWorkingTree; exportAsLatex] entitled: 'Exportar como LaTeX' categorized: 'Arbol';
act: [self saveWorkingTree; exportAsPdf] entitled: 'Exportar como PDF' categorized: 'Arbol';
act: [self viewExportedHtml] entitled: 'Ver HTML' categorized: 'Arbol'; act: [self viewExportedHtml] entitled: 'Ver HTML' categorized: 'Arbol';
act: [self messageNotImplementedYet] entitled: 'Ver PDF' categorized: 'Arbol'; act: [self messageNotImplementedYet] entitled: 'Ver PDF' categorized: 'Arbol';

View File

@ -136,6 +136,7 @@ GrafoscopioNode >> asMarkdown [
| markdownOutput | | markdownOutput |
markdownOutput := '' writeStream. markdownOutput := '' writeStream.
self exportPreambleTo: markdownOutput.
(self preorderTraversal) do: [ :eachNode | (self preorderTraversal) do: [ :eachNode |
(eachNode level > 0) (eachNode level > 0)
ifTrue: [(eachNode hasAncestorTaggedAs: 'invisible') | (eachNode tags = 'invisible') ifTrue: [(eachNode hasAncestorTaggedAs: 'invisible') | (eachNode tags = 'invisible')
@ -245,6 +246,37 @@ GrafoscopioNode >> demote [
] ]
{ #category : #exporting }
GrafoscopioNode >> exportCodeBlockTo: aStream [
"I convert the content of a node taged as 'código' (code) as pandoc markdown and put it Into aStream.
The code block is decorated with LaTeX commands for proper syntax highlighting using pygments.
Pdf exportation requires the installation of pygments and minted package for latex"
aStream nextPutAll: ('\begin{minted}{smalltalk}[frame=lines]'); lf.
aStream nextPutAll: (self body contents withInternetLineEndings); lf.
aStream nextPutAll: '\end{minted}';lf;lf.
^aStream contents
]
{ #category : #exporting }
GrafoscopioNode >> exportPreambleTo: aStream [
"comment stating purpose of message"
| configDict |
aStream nextPutAll: '---'; lf.
aStream nextPutAll: 'header-includes:'; lf.
aStream nextPutAll: ' - \usepackage{minted}'; lf.
aStream nextPutAll: ' - \usemintedstyle{friendly}'; lf.
(self header = '%config')
ifTrue: [
configDict := STON fromString: (self body).
aStream nextPutAll: 'title: ', (configDict at: 'title'); lf.
aStream nextPutAll: 'author: ', ((configDict at: 'author') at: 'given'), ' ', ((configDict at: 'author') at: 'family'); lf.
aStream nextPutAll: 'bibliography: ', (configDict at: 'bibliography'); lf.
aStream nextPutAll: 'abstract: ', '|'; lf; nextPutAll: (configDict at: 'abstract'); lf.
].
aStream nextPutAll: '---'; lf.
]
{ #category : #exporting } { #category : #exporting }
GrafoscopioNode >> flatten [ GrafoscopioNode >> flatten [
"I traverse the tree looking for node bodies containing 'Text' objects and transform them to "I traverse the tree looking for node bodies containing 'Text' objects and transform them to
@ -355,11 +387,32 @@ GrafoscopioNode >> level: anInteger [
level := anInteger level := anInteger
] ]
{ #category : #exporting }
GrafoscopioNode >> margin [
"I define the same margin of the page used for PDF exportations"
^'2 cm'
]
{ #category : #exporting }
GrafoscopioNode >> margins [
"I define each individual margin of the page used for PDF exportations"
| margins |
margins := Dictionary new
add: 'top' -> '3 cm';
add: 'bottom' -> '3 cm';
add: 'left' -> '2 cm';
add: 'right' -> '2 cm';
yourself.
^ margins
]
{ #category : #exporting } { #category : #exporting }
GrafoscopioNode >> markdownContent [ GrafoscopioNode >> markdownContent [
"Extracts the markdown of a node using body as content, header as title and level as hierarchical level of the title. "Extracts the markdown of a node using body as content, header as title and level as hierarchical level of the title.
If special nodes types are present, converts them into proper markup to be embedded inside markdown" If special nodes types are present, converts them into proper markup to be embedded inside markdown"
| markdown configDict embedNodes temporalBody invisibleChildren | | markdown embedNodes temporalBody invisibleChildren |
markdown := '' writeStream. markdown := '' writeStream.
(self class specialWords includes: self header) not & (self class specialWords includes: ((self header findTokens: $ ) at: 1)) not & (self tags = 'código') not (self class specialWords includes: self header) not & (self class specialWords includes: ((self header findTokens: $ ) at: 1)) not & (self tags = 'código') not
ifTrue: [ ifTrue: [
@ -380,16 +433,6 @@ GrafoscopioNode >> markdownContent [
] ]
]. ].
markdown nextPutAll: (temporalBody contents withInternetLineEndings ); crlf; crlf]. markdown nextPutAll: (temporalBody contents withInternetLineEndings ); crlf; crlf].
(self header = '%config')
ifTrue: [
configDict := STON fromString: (self body).
markdown nextPutAll: '---'; lf.
markdown nextPutAll: 'title: ', (configDict at: 'title'); lf.
markdown nextPutAll: 'author: ', ((configDict at: 'author') at: 'given'), ' ', ((configDict at: 'author') at: 'family'); lf.
markdown nextPutAll: 'bibliography: ', (configDict at: 'bibliography'); lf.
markdown nextPutAll: 'abstract: ', '|'; lf; nextPutAll: (configDict at: 'abstract'); lf.
markdown nextPutAll: '---'; lf. ].
((self header findString: '%idea') = 1) ((self header findString: '%idea') = 1)
ifTrue: [ ifTrue: [
embedNodes := self children select: [:each | ((each header findTokens: $ ) at: 1) = '%embed']. embedNodes := self children select: [:each | ((each header findTokens: $ ) at: 1) = '%embed'].
@ -407,11 +450,7 @@ GrafoscopioNode >> markdownContent [
ifTrue: [ ifTrue: [
invisibleChildren := self children. invisibleChildren := self children.
invisibleChildren ifNotNil: [ ] ]. invisibleChildren ifNotNil: [ ] ].
(self tags = 'código') (self tags = 'código') ifTrue: [ self exportCodeBlockTo: markdown ].
ifTrue: [
markdown nextPutAll: ('\begin{minted}{smalltalk}'); lf.
markdown nextPutAll: (self body contents withInternetLineEndings); lf.
markdown nextPutAll: '\end{minted}';lf].
^markdown contents ^markdown contents
] ]