Computadores, Diagramação, Editoração, Programação, Python, Scribus

Automatizando diagramação de notícias com Scribus e Python

Matéria montada automaticamente pelo script.

Matéria montada automaticamente pelo script.

Que tal abrir um quadro de texto no Scribus, rodar um script e obter rapidamente uma matéria jornalística montada, com foto, legenda e crédito da foto? E que tal levar todo um sistema editorial num pen drive? (Editor de texto, editor de fotos, paginador, saída em PDF/X-3). E que tal tudo isto com ferramentas gratuitas e de código aberto?

Essa foi minha idéia ao aprender Python e Scribus Scripting. Levar um sistema editorial de categoria profissional num pen drive. Instalei o X-Scribus, um Scribus especial para pen drives. Ele já tem o Ghostscript, Python e tudo o que é necessário para rodar em qualquer computador com Windows. Existe mais uma versão, o Portable Scribus 1.3.3.12, mas ele me apresentou problemas na visualização de impressão: não permitia a seleção de chapas (plates) individuais — ciano, magenta, amarelo ou preto, coisa importante para o ensino de seleção de cores.

Imagens

Para automatizar o Scribus, uma das primeiras providências é permitir ao Python do Scribus a manipulação de imagens. Para isso, usei PIL (Python Image Library).

No Linux, o Scribus usa o Python normal do sistema. Instale as bibliotecas PIL da forma usual de seu sabor de Linux. No Windows, o instalador do Python Image Library precisa de certas chaves no registro do Windows para saber em que lugar está instalado o sistema Python. Eu defini estas chaves para a pasta do Scribus, que é onde roda o interpretador Python no Windows. Ao baixar o PIL, cuide as versões: no Scribus versão 1.3.3 estável,  o Python é versão 2.4. No Scribus 1.3.4 Beta, o Python é versão 2.5.

Para registrar o Python do Scribus, o meu arquivo reg tem o seguinte:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Python]
[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore]
[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore\2.4]
[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore\2.4\InstallPath]
@="c:\\SD\\PortableApps\\X-Scribus\\Bin\\Scribus\\"
[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore\2.4\PythonPath]
@="c:\\SD\\PortableApps\\X-Scribus\\Bin\\Scribus\\Lib\\;c:\\SD\\PortableApps\\X-Scribus\\Bin\\Scribus\\DLLs\\"

[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore\2.5]
[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore\2.5\InstallPath]
@="c:\\SD\\Bin\\Scribus\\"
[HKEY_LOCAL_MACHINE\SOFTWARE\Python\Pythoncore\2.5\PythonPath]
@="c:\\SD\\Bin\\Scribus\\Lib\\;c:\\SD\\Bin\\Scribus\\DLLs\\"

Se você precisar registrar, copie este código, mude os caminhos para as pastas para casarem com seu sistema (em vermelho) e grave como texto simples, com a terminação .reg. Dê dois clics no arquivo para registrar as chaves no registro do Windows.

Depois de instalado o PIL, se as bibliotecas de imagem forem corretamente reconhecidas, não haverá erros ao rodar o script de montagem de matérias.

Repare que instalei tudo usando o HD. Depois de tudo instalado, copiei a pasta inteira para o pen drive. No caso, copiei a pasta X-Scribus para a pasta PortableApps (que é o padrão de aplicações portáteis que uso) do pen drive.

A seguir coloquei o script na pasta de scripts do Scribus, que no meu caso coloquei em c:\SD\PortableApps\X-Scribus\Bin\Scribus\Scripts.

No início do script existem algumas variáveis que podem ser modificadas pelo usuário, como a largura da valeta (gutter, espaço entre as colunas).

O script funciona assim: desenhe um retângulo ou selecione um. Vá ao menu Scripts, procure e rode este script. Aparecem diversas janelinhas de diálogo perguntando:

  • Em quantas colunas será dividida a área de colunas da matéria? Escolha 2 ou mais.
  • Qual a largura do espaço entrecolunas (gutter ou valeta)?
  • Qual o corpo (tamanho) do sobretítulo?
  • Qual o corpo do subtítulo?
  • Quantas fotos tem a matéria? Por enquanto, o script só aceita uma.
  • Quantas colunas ocupa a foto (de largura)? A foto é posicionada ao lado da primeira coluna de texto e agrupada com quadros para legenda e para crédito. As bibliotecas PIL são usadas para isto. As funções PIL medem a foto escolhida e o script calcula a altura do quadro de foto. Mais tarde, uso a tecla CTRL + Y para abrir o editor de texto interno do Scribus para editar os dois elementos (como se faz no Adobe inDesign). Na primeira linha vai a legenda e na linha de baixo vai o crédito.

Falta fazer as rotinas para manipular fotos no caso de uma matéria em apenas uma coluna. Se você escolher uma coluna, a foto será montada ao lado da matéria.

A seguinte seqüência de quadros mostra como funciona o script.

O quadro para título vai agrupado com o quadro para as colunas. Para editar o texto, uso a tecla CTRL + Y. Para importar texto, seleciono o grupo e uso CTRL + D (como no PageMaker e InDesign).

#!/usr/bin/env python2.4
# -*- coding: utf-8 -*-

"""
Build a newspaper story
By prof. MS. José Antonio Meira da Rocha
mailto:joseantoniorocha@gmail.com

http://meiradarocha.jor.br

Licença GPL
"""

import sys

###########################
# Assegura que está rodando
# dentro do Scribus
###########################
try:
	import scribus
except ImportError,err:
	print "This Python script is written for the Scribus scripting interface."
	print "It can only be run from within Scribus."
	sys.exit(1)

# Carrega algumas constantes Scribus usadas neste script
from scribus import UNIT_POINTS, LINE_SOLID, JOIN_MITTER, BUTTON_OK, ICON_WARNING

#########################
# USER IMPORTS GO HERE  #
#########################

#####################################
# Usuário pode mudar estes parâmetros
#####################################
numeroDeColunasPadrao = "3"
entrecolunasPadrao = "14.1732"  # 5mm
corpoDeTituloPadrao = "48"
corpoPadraoDoSobretitulo = "18"
proporcaoDeEntrelinha = 1.0

##########################################
# Constantes que NÃO devem ser modificadas
AROUND_FRAME = 1
BOUNDING_BOX = 2
CONTOUR_LINE = 3 

######################
# Locale strings
# Textos para tradução
######################
pedirParaAbrirDoc = "<h2>Abra um documento</h2>" \
	+"Ops! Abra um documento antes \nde rodar este comando."
pedirParaAbrirQuadro = "<h2>Desenhe um quadro</h2>\n" \
	+"Ops! Desenhe ou selecione um <b>quadro</b>\n" \
	+"na área em que você quer montar a matéria."
#
labelDeColunas = 'Colunas' #Number of columns
mensagemDeColunas = '<h2>Colunas</h2><p>Quantas colunas?</p>'  #How many columns?
#
labelDeCorpoDeTitulo = "Corpo do título" #quadroDeTitulo
mensagemDeCorpoDeTitulo = "<h2>Corpo do título</h2><p>Qual&nbsp;o&nbsp;corpo&nbsp;do&nbsp;título?</p>" #What the quadroDeTitulo size?
#
labelDeValetas = "Valetas"
mensagemDeValetas = "<h2>Valetas</h2><p>Qual&nbsp;o&nbsp;tamanho&nbsp;da&nbsp;valeta?\n(Espaço&nbsp;entrecolunas)"
#
labelDeSobretitulo = "Corpo do sobretítulo"
mensagemDeSobretitulo = "<h2>Corpo do sobretítulo</h2>\n<p><b>Qual&nbsp;o&nbsp;corpo&nbsp;do&nbsp;sobretítulo?</b>\n" \
	+ "(coloque&nbsp;zero&nbsp;se&nbsp;não&nbsp;houver&nbsp;sobretítulo)"
#
textFlowsAroundFrame = 'Abra a imagem'
filtroDeImagens = 'Arquivos de imagens (*.jpg *.png *.tiff *.tif)'
#
labelDeImportarTexto = "Abra o texto"
filtroDeArquivosTexto = "Arquivos de texto (*.txt *.html)"
#
labelDeLarguraDeImagem = "Largura da imagem"
mensagemDeLarguraDeImagem = "<h2>Largura&nbsp;da&nbsp;Imagem</h2>\nQuantas&nbsp;colunas&nbsp;a&nbsp;imagem&nbsp;ocupará?"
larguraDeColunasPadrao = "1"
#
labelDeImagem = "Quantas fotos"
mensagemDeImagem = "<h2>Quantas fotos?</h2>\n<p>Quantas&nbsp;fotos&nbsp;a&nbsp;matéria&nbsp;tem?"
numeroDeImagemPadrao = "1"

labelDeQuadroDeTitulo = "Montar matéria"

labelErroDeImportacao = "Não importei o arquivo"
msgDeErroDeImportacao = "<h2>Não importei o arquivo</h2><p>Desculpe-me, não importei o arquivo por algum detalhe de formato incompatível ou arquivo não encontrado. <b>Sem problema</b>, tente de novo manualmente nais tarde.</p>"

labelAbreDoc = "Abra um documento"
dizAbreDoc = "<h2>Abra um documento</h2><p>Por favor, este comando exige que você abra um documento.</p>"

####################
# End Locale strings
####################

try:
	import Image
except ImportError,err:
	print "This Python script is written for the PIL graphic interface."
	print "It should be instaled in Scribus Python tree."
	sys.exit(1)

def pedeNumeroDeColunas():
	"""Pede número de colunas de texto que terá a matéria"""

	numeroDeColunas = scribus.valueDialog(
		labelDeColunas,
		mensagemDeColunas,
		numeroDeColunasPadrao
	)
	if not numeroDeColunas:
		sys.exit()
	try:
		return int(numeroDeColunas)
	except:
		return numeroDeColunasPadrao

def pedeCorpoDoTitulo():
	"""Pede tamanho das letras (corpo) do título, em pontos tipográficos."""
	corpoDeTitulo = scribus.valueDialog(labelDeCorpoDeTitulo, mensagemDeCorpoDeTitulo, corpoDeTituloPadrao)
	if not corpoDeTitulo:
		sys.exit()
	try:
		return float(eval(corpoDeTitulo))
	except:
		return float(corpoDeTituloPadrao)

def pedeEntrecolunas():
	"""Pede o espaço entre as colunas de texto (gitter, valeta), em pontos tipográficos"""
	entrecolunas = scribus.valueDialog(labelDeValetas, mensagemDeValetas, entrecolunasPadrao)
	if not entrecolunas:
		sys.exit()
	try:
		return float(entrecolunas)
	except:
		return entrecolunasPadrao

def pedeCorpoDoSobretitulo():
	"""Pede tamanho das letras (corpo) do sobretítulo, em pontos tipográfico"""
	corpoDoSobretitulo = scribus.valueDialog(labelDeSobretitulo, mensagemDeSobretitulo, corpoPadraoDoSobretitulo)
	if not corpoDoSobretitulo:
		sys.exit()
	try:
		return float(eval(corpoDoSobretitulo))
	except:
		return float(corpoPadraoDoSobretitulo)

def pedeImagem():
	"""Pergunta por fotos na matéria"""
	temImagem = scribus.valueDialog(labelDeImagem, mensagemDeImagem, numeroDeImagemPadrao)
	if not temImagem:
		sys.exit()
	try:
		return temImagem
	except:
		return temImagem

def pedeTexto(quadroDeTitulo):
	"""Load text file"""

	sourceCharcode = 'iso-8859-15' # change it to ur language
	# Diálogo de procurar arquivo
	textFile = scribus.fileDialog(labelDeImportarTexto,filtroDeArquivosTexto,"", haspreview=1, issave=True) # issave=False shows "Save" button
	if textFile:
		try:
			t = open(textFile).read()
			t = unicode(t, sourceCharcode)
		except:
			scribus.messageBox(
				labelErroDeImportacao,
				msgDeErroDeImportacao,
				ICON_WARNING,
				BUTTON_OK
			)
			t=""
			return t
	else:
		t=""

	return t

def flow(frame,mode):
	"""Compatibiliza Scribus 1.3.3 e 1.3.4"""
	try:
		scribus.textFlowsAroundFrame(frame, mode) # Scribus 1.3.3
	except:
		scribus.textFlowMode(frame, mode)		 # Scribus 1.3.4

def pedeColunasDeImagem():
	"""Solicita a quantidade de colunas que a foto vai ocupar."""
	colunasDaFoto = scribus.valueDialog(
	labelDeLarguraDeImagem,
	mensagemDeLarguraDeImagem,
	larguraDeColunasPadrao
	)
	if not colunasDaFoto:
		sys.exit()
	try:
		return float(eval(colunasDaFoto))
	except:
		return float(larguraDeColunasPadrao)

def pedeFoto():
	"""	Escolhe arquivo de foto
	scribus.fileDialog('caption', ['filter', 'defaultname',haspreview, issave])"""

	# Abre diálogo para escolha de arquivo
	arquivoDaFoto = scribus.fileDialog(
		textFlowsAroundFrame,
		filtroDeImagens,
		"",  # Nome default do arquivo
		haspreview=1,
		issave=True
	)

	# Tenta abrir arquivo fornecido
	try:
		foto = Image.open(arquivoDaFoto)  # uso da biblioteca PIL
	except:
		scribus.messageBox(
			labelErroDeImportacao,
			msgDeErroDeImportacao,
			ICON_WARNING,
			BUTTON_OK
		)
		foto = ""
	return foto,arquivoDaFoto

def montaQuadroDaFoto(quadroDeColunas):
	"""Build a image frame with credit and legenda
	based in text frame number of columns"""

	#
	foto,arquivoDaFoto = pedeFoto()
	try:
		larguraDaFoto,alturaDaFoto = foto.size  # para pegar o tamanho da imagem em pixels
	except:
		larguraDaFoto,alturaDaFoto = 4,3  # Se não conseguir, define proporção 4 por 3

	# Escolhe quantas colunas a foto vai "abrir"
	colunasDaFoto = pedeColunasDeImagem()

	# Calcula largura da foto
	entrecoluna = scribus.getColumnGap(quadroDeColunas)
	colunasDeTexto = scribus.getColumns(quadroDeColunas)

	# Define o tamanho da foto
	larguraDoQuadroDeColunas,alturaDoQuadroDeColunas = scribus.getSize(quadroDeColunas)

	larguraDaColuna = (larguraDoQuadroDeColunas - (entrecoluna*(colunasDeTexto-1))) / colunasDeTexto

	# calcula posição da imagem
	quadroDeColunasEsquerda, quadroDeColunasTopo = scribus.getPosition(quadroDeColunas)

	# Posiciona foto a partir da segunda coluna de texto
	quadroDaFotoEsquerda = quadroDeColunasEsquerda + larguraDaColuna + entrecoluna
	quadroDaFotoTopo = quadroDeColunasTopo

	# Calcula largura e altura da imagem
	larguraDoQuadroDaFoto = colunasDaFoto * larguraDaColuna + (entrecoluna * (colunasDaFoto - 1))
	alturaDoQuadroDaFoto = larguraDoQuadroDaFoto * alturaDaFoto / larguraDaFoto

	# Cria quadro de imagem com a foto
	quadroDaFoto = scribus.createImage(quadroDaFotoEsquerda, quadroDaFotoTopo, larguraDoQuadroDaFoto, alturaDoQuadroDaFoto)

	# Define fluxo para "Afastar texto"
	flow(quadroDaFoto, AROUND_FRAME) 

	# Define formatação gráfica do quadro de foto
	scribus.setLineWidth(	   0.8, quadroDaFoto)
	scribus.setLineColor(   "Black", quadroDaFoto)
	scribus.setLineShade(	   100, quadroDaFoto)
	scribus.setLineStyle(LINE_SOLID, quadroDaFoto)
	scribus.setLineJoin(JOIN_MITTER, quadroDaFoto)
	try:
		scribus.loadImage(arquivoDaFoto, quadroDaFoto)
	except:
		print "Não pude carregar a imagem."

	# Calcula escala da imagem para caber no quadro
	escalaDaFoto = larguraDoQuadroDaFoto / larguraDaFoto

	# Resescalona quadro de imagem
	scribus.scaleImage(escalaDaFoto, escalaDaFoto, quadroDaFoto)

	########################################
	# LEGENDA
	########################################
	# Calcula dimensões do quadro de legenda
	quadroDaLegendaTopo = quadroDaFotoTopo + alturaDoQuadroDaFoto
	alturaDoQuadroDaLegenda = entrecoluna * 2
	# Cria quadro de legenda
	quadroDaLegenda = scribus.createText(quadroDaFotoEsquerda, quadroDaLegendaTopo, larguraDoQuadroDaFoto, alturaDoQuadroDaLegenda)
	#
	# Melhoria: Colocar leitor de input para escrever legenda

	# Liga "afastador de texto"
	flow(quadroDaLegenda, AROUND_FRAME)

	##########################################
	# CREDITO
	##########################################
	# Define medidas do quadro para crédito de foto
	quadroDaFotoDireita = quadroDaFotoEsquerda + larguraDoQuadroDaFoto
	quadroDaFotoBaixo = quadroDaFotoTopo + alturaDoQuadroDaFoto
	# Cria quadro de crédito
	quadroDoCredito = scribus.createText(quadroDaFotoDireita, quadroDaFotoBaixo, alturaDoQuadroDaFoto, entrecoluna)
	#
	# Melhoria: Colocar input de crédito para escrever credito
	#   if not finalizado
	#	  processaNaoFinalizado()

	# Liga "afastador de texto"
	flow(quadroDoCredito, AROUND_FRAME)

	# Agrupa os elementos foto, legenda e crédito
	scribus.groupObjects([quadroDaFoto, quadroDaLegenda, quadroDoCredito])

	# Se tiver a legenda e crédito no mesmo arquivo que o texto da matéria
	#scribus.linkTextFrames(quadroDeTitulo, quadroDaLegenda)

	# Liga os textos da legenda e dos créditos
	scribus.linkTextFrames(quadroDaLegenda, quadroDoCredito)

	# Se tiver a legenda e crédito no mesmo arquivo que o texto da matéria
	#scribus.linkTextFrames(credit, quadroDeColunas)

	# Deixa o quadro de legenda "em pé"
	scribus.rotateObject(90, quadroDoCredito)

def montaMateria(espacoDaMateria):
	""" Manipula um bloco de notícia """

	# Pega as coordenadas X e Y do objeto selecionado
	esquerdaDoQuadro, topoDoQuadro = scribus.getPosition(espacoDaMateria)
	# Pega a largura e altura do quadro
	larguraDoQuadro, alturaDoQuadro = scribus.getSize(espacoDaMateria)
	# Apaga objeto original, que era usado só pra marcar o espaço.
	scribus.deleteObject(espacoDaMateria)

	# Cria um bloco de texto com as medidas extremas do objeto
	# E deleta o objeto (que pode ser até uma linha)
	quadroDeTitulo = scribus.createText(esquerdaDoQuadro, topoDoQuadro, larguraDoQuadro, alturaDoQuadro)

	# Pergunta pelo número de colunas
	numeroDeColunas = pedeNumeroDeColunas()

	# Pergunta pelo espaço entre-colunas
	entrecolunas = pedeEntrecolunas()

	# Pergunta pelo tamanho do título em pontos
	corpoDeTitulo = pedeCorpoDoTitulo()

	# Pergunta pelo tamanho do antetítulo
	corpoDoSobretitulo = pedeCorpoDoSobretitulo()

	#######################################
	# TÍTULO
	#######################################
	# Calcula o tamanho total dos títulos
	alturaDoQuadroDeTitulo = (corpoDeTitulo + corpoDoSobretitulo) * proporcaoDeEntrelinha
	direitaDoQuadro = esquerdaDoQuadro + larguraDoQuadro
	# Redimensiona quadro de título
	scribus.sizeObject(larguraDoQuadro, alturaDoQuadroDeTitulo, quadroDeTitulo)
	# Define o tipo de fluxo de texto: "afastar texto"
	flow(quadroDeTitulo, AROUND_FRAME)

	#######################################
	# COLUNAS DE TEXTO
	#######################################
	# Define medidas do quadro de textos
	topoDasColunas = topoDoQuadro + alturaDoQuadroDeTitulo
	alturaDasColunas = alturaDoQuadro - alturaDoQuadroDeTitulo
	# Cria quadro de texto
	quadroDeColunas = scribus.createText(esquerdaDoQuadro, topoDasColunas, larguraDoQuadro, alturaDasColunas)
	# Define o fluxo de texto como "afastar texto"
	flow(quadroDeColunas, AROUND_FRAME)
	# Determina colunagem
	scribus.setColumnGap(entrecolunas, quadroDeColunas)
	scribus.setColumns(numeroDeColunas, quadroDeColunas)

	#######################################
	# LINCA TEXTOS
	# Linca quadros de título e de texto
	#######################################
	scribus.linkTextFrames(quadroDeTitulo,quadroDeColunas)
	storyGroup = scribus.groupObjects([quadroDeTitulo, quadroDeColunas])

	#######################################
	# PEGA TEXTO
	#######################################
	# Quadro de escolha de arquivo
	text = pedeTexto(quadroDeTitulo)

	try:
		#scribus.insertText(text,-1,quadroDeTitulo)  # para ANEXAR ao final em vez de substituir
		scribus.setText(text,quadroDeTitulo)
	except:
		text="SobretítulonTítulonAutor da matérianComplemento ao autornPrimeiro ParágrafonOutros parágrafosOutros parágrafos..."
		scribus.setText(text,quadroDeTitulo)

	#######################################
	# PEGA FOTO
	#######################################
	# Ask image
	temImagem = pedeImagem()
	if temImagem:
		montaQuadroDaFoto(quadroDeColunas)

def manipulaSelecao():
	""" Gerencia objetos selecionados """

	# Pega o objeto selecionado
	story = scribus.getSelectedObject(0)
	# Se há apenas um objeto selecionado
	if story and scribus.selectionCount() == 1 :
	#	if story:
		montaMateria(story)
		scribus.docChanged(True)
	else:
		#Melhoria pra o futuro:
		#por default, abrir uma matéria do tamanho da página
		# De momento, só avisa
		scribus.messageBox(
			labelDeQuadroDeTitulo,
			pedirParaAbrirQuadro,
			ICON_WARNING,
			BUTTON_OK
		)

def manipulaDocumento():
	"""Manipula documentos """
	# Se há documento aberto
	if scribus.haveDoc():
		#Desliga redraw
		scribus.setRedraw(False)
		#Guarda unidades do usuário # Save unit
		unit = scribus.getUnit()
		#Define novas unidades como "pontos tipográfico"
		scribus.setUnit(UNIT_POINTS)

		#############################
		# Manipula objeto selecionado
		#############################
		manipulaSelecao()

		#Recupera medidas do usuário
		scribus.setUnit(unit)
	else:  # Senão há documento aberto, avisa.
		scribus.messageBox(
			labelAbreDoc,
			dizAbreDoc,
			ICON_WARNING,
			BUTTON_OK
		)

def myCode():
	""" User code """
	#########################
	#  USER CODE GOES HERE  #
	#########################

	# Gerencia documento
	manipulaDocumento()

	#########################
	#  USER CODE ENDS HERE  #
	#########################

def main(argv):
	"""Default main entry point"""
	myCode()

def main_wrapper(argv):
	try:
		scribus.statusMessage("Rodando o script...")
		scribus.progressReset()
		main(argv)
	finally:
		if scribus.haveDoc():
			scribus.setRedraw(True)
		scribus.statusMessage("")
		scribus.progressReset()

if __name__ == '__main__':
	main_wrapper(sys.argv)

Bibliografia

  1. ROSSUM, Guido Van. Python Tutorial. Capítulo 4, More control flow tools, FOR statements. Site web disponível em: <http://www.python.org/doc/2.4.4/tut/node6.html#SECTION006200000000000000000>. Acesso em 25. jul. 2008.
  2. SCRIBUS. Arquivo de ajuda. Versão 1.3.3.12. Capítulo For Developers, seção Scripter API, página Page Comands. Disponível no programa através da tecla F1.


4 comentários

  1. Wanderson Costa disse:

    Tenho crescido lendo seus artigos. Você pode me enviar um script para edição de matérias no Indesign?

  2. Camila Schafer disse:

    Olá professor

    Sou estudante de jornalismo e me formo em 2010. Gosto muito de diagramação e trabalho bastante com isso na agência onde faço um estágio. Gostaria de seguir na área, mas preciso de orientação quanto a quais cursos fazer (e se é preciso), se é uma área que dá retorno ($$), onde posso procurar por oportunidades, etc.

    OBS: Responda para meu e-mail.

    Muito obrigado
    Camila

  3. [...] ainda exigem que se abra um quadro para os títulos e outro quadro para as colunas de texto. Criei script noScribus que já faz a diagramação de matérias automaticamente , depois que o diagramador especifica tamanhos de títulos e quantidades de colunas. Estou [...]

Deixe uma resposta

XHTML: Você pode usar estas tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notifique-me sem que eu precise comentar