Macro de dibujo de viñetas en plantilla de guion de cómic LibreOffice - Grandamakulo - 31-10-2021
A raíz de hacer una plantilla para redactar guiones de historietas que se adaptase a mi forma de trabajar, pensé que debía añadirle una herramienta que permitiese hacer un diagrama de viñetas sin necesidad de gastar la, más o menos, hora por cada 15-18 páginas.
La cuestión planteada en https://gambas-es.org/showthread.php?tid=645 venía al caso para poder hacer un diagrama de viñetas que ayudase al dibujante «víctima» del guionista de turno. Esto es, el «escribidor» realiza un guion con la plantilla y ésta, de manera automática, fabrica un esquema de viñetas. Para tal propósito son necesaria dos cosas:
- Que las páginas y las viñetas estén formateadas con los párrafos correspondientes.
- Que el texto de las viñetas indique el tamaño y posición según el método sugerido por Peio Soria.
Este método es muy simple. Como explico en https://www.faneo.es/forum/forum/guion-y-narrativa-43/topic/el-m%C3%A9todo-de-peio-soria-para-caracterizar-vi%C3%B1etas-894/?post=11068#11068, En su manual «Mi guion de cómic», que está para bajar libremente en pdf desde su página, Peio Soria describe el que, para mí, es el método más lógico y sencillo. Se trata de emplear unas fracciones en vertical y en horizontal, de la manera 2/3Vx2/4H, por ejemplo. ¿Cómo se interpretaría? Fácil, 2/3V significa que se toma el segundo de los tres tercios posibles de la división vertical de la página, esto es, columnas. Además se toma el segundo de las cuatro posibles partes de división horizontal, filas, de la página. Superponiendo ambos, resulta la viñeta que queremos indicar.
Para abarcar varias partes en el caso de alguna viñeta más irregular o una que ocupe toda unidad, se pueden emplear nomenclaturas especiales.
Véase un ejemplo de cómo queda escrito:
De esta manera, al ejecutar la macro, se obtiene:
Documento que ya se puede enviar para que el dibujante pueda interpretar más fácilmente lo que dice el guionista y, después,... hacer lo que le venga en gana .
Además, la macro permite:
- Solapamiento de viñetas —como en la página 37 del ejemplo—.
- Cambio INMEDIATO de formato de página —apaisado, vertical, A5, B5, cuadrado, fanzine...— con sólo introducir un número.
- Detecta errores en la nomenclatura e indica el lugar en el que se produce.
- Se le ha añadido un apéndice de estadísticas que permite ver, aparte de las palabras y caracteres que ya indica el programa con «contar palabras», el número de páginas del cómic, el número bruto de viñetas y el número de bocadillos.
A esta macro, después de pelearme mucho, muchísimo, más todavía, con los mal documentados y dispersas especificaciones del UNO de Star BASIC —al menos así le pareció a éste, su humilde servidor—, logré terminarla en una versión más o menos útil:
Código: REM ***** BASIC *****
' DIBUJAR ESQUEMAS PARA GUION DE HISTORIETAS Y ESTADÍSITCAS.
' SOFTWARE LIBRE
' --------------
'
' Grandamakulo, 2021
' grandamakulo@gmail.com
'
' * Puedes:
' Distribuirlo
' Modificarlo
' Regalarlo
' Si te place, acredítame
'
' * No puedes:
' Cobrar por él o por sus variaciones directas
' Si quieres hacerlo, ponte en contacto conmigo
' —Hay muchas fundaciones a las que ayudar—
'
' * Garantías:
' Estás de guasa, ¿no?
' Si se te funde la lavadora o se te hace un
' desconchón en la pared, soluciónalo tú.
'
' ESTE PROGRAMA CONSIDERA LAS TRES --O CUATRO--
' LEYES DE LA ROBÓTICA. Más o menos.
Option Explicit
Const Si As Boolean = True
Const No As Boolean = False
Const sC As String = """"
Const sA As String = "'"
Sub DibujaEsquema()
' A partir de los datos del formato de página que introduce el usuario,
' del número de páginas y de la información que el usuario ha establecido
' en el tipo de párrafo viñeta, se dibuja en SVG —y se guarda en el mismo
' directorio que el Documento— un ESQUEMA DE VIÑETAS.
Dim oDoc As Object 'Documento actual
Dim oEnu As Object 'Partes del documento actual
Dim oTex As Object 'Un elemento texto de oEnu
Dim iPag As Integer 'Número de página
Dim iVin As Integer 'Número de viñeta en cada página
Dim oSitio As Object
Dim _iRel As Double 'Relación entre alto y ancho
Dim _iAnM As Double 'Ancho de marco = 210,0224103814 mm eq A4
Dim _iAlM As Double 'Alto del marco = _iAnt * _iRel
Dim _iCaM As Double 'Ancho de calle marco = 5 mm
Dim _iCaP As Double 'Ancho de calle página = 5 mm
Dim _iCaV As Double 'Ancho de calle viñeta = 2 mm
Dim _iAnP As Double 'Ancho de página
Dim _iAlP As Double 'Alto de página
Dim _sCoM As String 'Color marco
Dim _sCoP As String 'Color página
Dim _sCoB As String 'Color borde viñeta
Dim _sCoV As String 'Color viñeta
Dim _iAnB As Double 'Ancho borde viñeta
Dim _sFuP As String 'Fuente página
Dim _iFTP As Integer 'Tamaño fuente página
Dim _sFuV As String 'Fuente viñeta
Dim _iFTV As Integer 'Tamaño fuente viñeta
Dim iXM As Double 'Coordenada X origen del marco actual
Dim iYM As Double 'Coordenada Y origen del marco actual
Dim iXP As Double 'Coordenada X origen de la página actual
Dim iYP As Double 'Coordenada Y origen de la página actual
Dim iXV As Double 'Coordenada X origen de la viñeta actual
Dim iYV As Double 'Coordenada Y origen de la viñeta actual
Dim iAnV As Double 'Ancho de la viñeta actual
Dim iAlV As Double 'Alto de la viñeta actual
Dim iKK As Byte
Dim iFil As Byte
Dim iCol As Byte
Dim iVis As Variant
Dim Paso As String 'Variable comodín
Dim tSVG As String 'Cadena SVG resultado
On ERROR GOTO Errr
'Tamaño y orientación de la página
Paso="A4 vertical: " & sqr(2) & Chr(13)
Paso=Paso & "A4 Horizontal: " & 1/sqr(2) & Chr(13)
Paso=Paso & "Cuadrado: " & 1 & Chr(13)
Paso=Paso & "O un número cualquiera como proporción entre alto y ancho."
_iRel=InputBox(Paso, "Formato", sqr(2))
if _iRel<=0 then end
Paso=""
'Iniciar variables de color, forma y fuentes
_sCoM="#000080"'"#000000FF"
_sCoP="#FFFFFF"
_sCoB="#008080"
_sCoV="#00FFFF80"
_iAnB=2
_sFuP="Liberation Mono"
_sFuV="Liberation Mono"
_iFTV=16
_iFTP=72
_iAnM= 210.0224103814*3.779527559055
_iAlM=_iAnM*_iRel
_iCaM=5
_iCaP=5
_iCaV=1
_iAnP=(_iAnM-3*_iCaP)/4
_iAlP=(_iAlM-5*_iCap)/4
tSVG="<svg version=" & sC & "1.1" & sC & " xmlns=" & sC & "http://www.w3.org/2000/svg" & sC
tSVG=tSVG & " xmlns:xlink=" & sC & "http://www.w3.org/1999/xlink" & sC & ">"
'Primer marco
iXM=0
iYM=0
tSVG=tSVG & RectSVG(iXM, iYM, _iAnM, _iAlM, _sCoM) & Chr(13)
oDoc=ThisComponent
oEnu=oDoc.Text.createEnumeration
While oEnu.hasMoreElements
oTex=oEnu.nextElement
If oTex.supportsService("com.sun.star.text.Paragraph") Then
If oTex.ParaStyleName=("CC_Página") Then
iPag=iPag+1
iVin=0
'¿Marco nuevo? A dibujarlo
iKK=iPag MOD &H10
If iKK=0 Then
iYM=0
iXM=(iPag \ &H10)*(_iAnM+_iCaM)
tSVG=tSVG & RectSVG(iXM, iYM, _iAnM, _iAlM, _sCoM) & Chr(13)
End If
'Dibuja la página
Paso = iPag
iCol=iKK MOD 4
iFil=iKK \ 4
iYP=iYM+_iCaP+(_iCaP+_iAlP)*iFil
iXP=iXM+_iCaP+_iAnP*iCol+((iCol+1) MOD 2)*_iCap
tSVG=tSVG & RectSVG(iXP, iYP, _iAnP, _iAlP, _sCoP,"1","#000000",_sFuP, _iFTP, "gray",Paso) & Chr(13)
End If
If oTex.ParaStyleName=("CC_Viñeta") Then
iVin=iVin+1
'Dibuja la viñeta
'Interpreta posición y tamaño
iVis=SoriaVin(oTex.String, Str(iPag & "." & iVin))
iYV=iVis(0,0)*_iAlP+iYP
iXV=iVis(1,0)*_iAnP+iXP
iAnV=iVis(1,1)*_iAnP
iAlV=iVis(0,1)*_iAlP
Paso=iPag & "." & iVin
tSVG=tSVG & RectSVG(iXV, iYV, iAnV, iAlV, _sCoV, "1", _sCoB, _sFuV, _iFTV,"gray",Paso) & Chr(13)
End If
End If
Wend
tSVG=tSVG & "</svg>"
GlobalScope.BasicLibraries.loadLibrary("Tools")
GuardaArchivo(tSVG, Tools.Strings.DirectoryNameoutofPath(oDoc.URL, "/") & "/EsquemaVinetas.svg")
'Print tSVG
MsgBox("¡Terminado!")
Exit Sub
Errr:
Reset
MsgBox("Numeración incorrecta en la viñeta: " & iPag & "." & iVin & Chr(13) & oTex.String)
End Sub
Sub CuentaVinetas()
'Cuenta páginas, bocadillos y viñetas por tipo de párrafo y lo muestra en un mensaje
Dim oDoc As Object
Dim oEnu As Object
Dim oTex As Object
Dim iPag As Integer
Dim iVin As Integer
Dim iBoc As Integer
Dim Paso As String
oDoc=ThisComponent
oEnu=oDoc.Text.createEnumeration
While oEnu.hasMoreElements
oTex=oEnu.nextElement
If oTex.supportsService("com.sun.star.text.Paragraph") Then
If oTex.ParaStyleName=("CC_Viñeta") Then iVin = iVin+1
If oTex.ParaStyleName=("CC_Página") Then iPag = iPag+1
If oTex.ParaStyleName=("CC_Bocadillo") Then iBoc = iBoc+1
End If
Wend
Paso = "Páginas: " & iPag & Chr(13)
Paso = Paso & "Viñetas: " & iVin & Chr(13)
Paso = Paso & "Bocadillos: " & iBoc
MSGBOX (Paso, 64, "Estadísitcas")
End Sub
Private Function RectSVG (iX As Double, iY As Double, iAnc As Double, iAlt As Double, sFondo As String, Optional iBorde As Double, Optional sBorde As String, Optional sFuente As String, Optional iTam As Integer, Optional sColor As String, Optional tTexto As String) As String
'Genera un texto SVG con un rectángulo y un texto dentro.
Dim Paso as String
'Posición
Paso=Paso & "<rect x=" & sC & Int(iX) & sC & " y=" & sC & Int(iY) & sC
'Tamaño
Paso=Paso & " width=" & sC & Int(iAnc) & sC & " height=" & sC & Int(iAlt) & sC
'Color
Paso=Paso & " style=" & sC & "fill:" & sFondo
'Borde, si se le añade
If Not IsMissing(sBorde) Then
Paso=Paso & ";stroke:" & sBorde & ";stroke-width:" & iBorde & "px"
End If
Paso=Paso & sC & "/>" & Chr(13)
If Not IsMissing(tTexto) Then
'Texto, si se le añade
'Fuente
Paso=Paso & "<text font-family=" & sC & sFuente & sC & " font-size=" & sC & iTam & sC & " fill=" & sC & sColor & sC
'Posición
Paso=Paso & " x=" & sC & Int(iX+iAnc/2) & sC & " y=" & sC & Int(iY+iAlt/2) & sC
'Centrar
Paso=Paso & " text-anchor=" & sC & "middle" & sC & " alignment-baseline=" & sC & "center" & sC
'Texto
Paso=Paso & ">" & tTexto & "</text>"
End If
RectSVG=Paso
End Function
Private Sub GuardaArchivo(tTexto as String, sRuta as String)
Dim iLibre as Integer
sRuta = ConvertToUrl(sRuta)
iLibre = FreeFile
Open sRuta For Output As #iLibre
Print #iLibre,tTexto
Close #iLibre
End Sub
Private Function SoriaVin(sTex As String, Donde As String) As Variant
Dim sGGG As String 'Texto Soria en mayuúsculas y sin espacios
Dim sMMM() As String 'Matriz para tratar el texto
Dim sTTT() As String 'Submatriz
Dim iPX (0 To 1, 0 To 1) As Double '0 Hor ;1 Ver | 0 Origen; 1 Ancho
Dim iPA (0 To 1, 0 To 2) As Double '0 Hor ;1 Ver | 0 Desde; 1 Hasta ; 2 De
Dim i As Byte 'Contador
Dim k As Byte 'Contador
sGGG = Ucase(Trim(sTex))
if Not IsNumeric(Left(sGGG,1)) Then
'Si no comienza por número, viñeta a toda página
sGGG="1/1VX1/1H"
End If
sMMM=Split(sGGG," ")
sGGG=sMMM(0)
sMMM=Split(sGGG,"X")
If Ubound(sMMM)=0 Then
Redim Preserve sMMM(0 To 1)
if Instr(sMMM(0),"V") Then sMMM(1)="1/1H" Else sMMM(1)="1/1V"
End If
For i=0 To 1
sGGG=sMMM(i)
If InStr(sGGG,"H") Then k=0 Else k=1
sGGG=Left(sGGG,Len(sGGG)-1)
sTTT=Split(sGGG, "/")
iPA(k,2)=sTTT(Ubound(sTTT))
sTTT=Split(sTTT(0),"-")
If Ubound(sTTT)=1 Then
iPA(k,0)=sTTT(0)
iPA(k,1)=sTTT(1)
Else
iPA(k,0)=sTTT(0)
iPA(k,1)=sTTT(0)
End If
iPX(k,0)=(iPA(k,0)-1)/iPA(k,2)
iPX(k,1)=(iPA(k,1)-iPA(k,0)+1)/iPA(k,2)
Next i
SoriaVin=iPX
End Function
|