Exporting: Improving PDF exportation via XeLaTeX for unicode support. Still some leftovers proper cleaning needs to be debugged.
This commit is contained in:
parent
d08470823a
commit
47a9e4bf8f
@ -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
|
||||||
|
]
|
||||||
|
@ -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';
|
||||||
|
|
||||||
|
@ -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
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user