#!/usr/bin/perl -s # Best-viewed with a tab size of 2 spaces (:set tabstop=2 in vi) # #}, #{, #( and #) comments used for correct parenthesis match in vi. #use strict; use locale; use XML::DT; =head1 NAME bb2html - Tradutor do Bullarium Bracarense de XML para HTML. =cut =head1 SINOPSE B [-bulaidx] bb.xml =cut =head1 DESCRIPTION B recebe uma implementação da I, i.e., uma instância da gramática definida pelo B do Bullarium Bracarense (F), e gera três ficheiros HTML e dois CSS para a directoria actual: =over =item * bb.html =item * bbtoc.html =item * bbcts.html =item * bbtoc.css =item * bbcts.css =back A opção B<-bulaidx> cria uma tabela de conteúdo com hyperlinks directos para as bulas, através dos seus identificadores. B faz uso do melhor módulo Perl de processamento de informação XML, o B. =cut $\ = "\n"; # separador de saída de registo ###################################################################### # Título HTML my $title = "Bulário Bracarense - ". "Sumários de Diplomas Pontifícios dos Séculos XI a XIX"; ###################################################################### # ficheiro a processar: $ARGV[0] (my $xmlfile = shift) or die ("Sintaxe: bb2html [-bulaidx] bb.xml\n"); my $header = ""; # cabeçalho da bula my $who = ""; # emissor da bula (1) my $whom = ""; # um destinatário da bula my $whoms = ""; # destinatários da bula (2) my $content = ""; # conteúdo da bula my $linkage; # conectivo de ligação (1)-(2) my $idxitem = 0; # contador $idxitem (p/ lista enumerada após intro) my $architem = 0; # contador $architem (usado nas refs manuscritas) my $current_bula_id = "B1"; # id da bula my $abb = ""; # abreviatura do par (abbsigla) my $sigla = ""; # sigla do par (abbsigla) my %anthropos; # ff de pessoas (p/ índice antroponimico) my %topos; # ff de lugares (p/ índice toponímico) my %geotopos; # ff de info geo de lugares (aux de %topos) my %addgeotopos; # ff de info adicional geo lugares (aux de %geotopos) my $agglen = 3; # comprimento mínimo de lista de números consectivos # para q se crie uma abreviatura desses números # Ex.: 1, 2, 3 -> 1 a 3; 51, 52, 53, 54 -> 51 a 54 # (p/ índices) my $anthropos_or_topos = ''; # ('A', 'T') = (anthropos, topos) # indicador do q se esta a processar my $bulavsp = '

'; # espaço vertical entre bulas my $bulahdrvsp = '
'; # espaço vertical entre bula e header, # i.e. entre a linha do id da bula # e a do bloco que contem who e whom my $tabcapvsp = '

'; # espaço vertical entre as tabelas e os # seus títulos do quadro sincrónico my $cntqtedvsp = '
'; # espaço vertical entre contents e addon my $trfbulavsp = '

';# espaço vertical entre bulas transferidas my $bbmainfile = "bb.html"; # nome do ficheiro principal # (o q contem o frameset) my $bbtocfile = "bbtoc.html"; # nome do ficheiro q contem o frame # do lado esquerdo (table of contents) my $bbctsfile = "bbcts.html"; # nome do ficheiro do frame do # lado direiro (conteúdo) my $bbcreditsfile = "credits.html"; # nome do ficheiro dos créditos my $bbtoccssfile = "bbtoc.css"; # style sheet p/ $bbtocfile my $bbctscssfile = "bbcts.css"; # style sheet p/ $bbctsfile # carregamento da lista de apelidos referentes # a nomes que não # respeitam a REGRA 1 (=head2 REGRA 1) my %anthropos_spnames = &load_anthspnames; my %rmnarb = ( 'I' => 1, 'V' => 5, 'X' => 10, 'L' => 50, 'C' => 100, 'D' => 500, 'M' => 1000 ); my %arbrmn = ( 1 => 'I', 5 => 'V', 10 => 'X', 50 => 'L', 100 => 'C', 500 => 'D', 1000 => 'M' ); sub ssort { my $chars = '[A-Za-zÀÁÂÃÈÉÊÌÍÎÒÓÔÕÙÚÛàáâãèéêìíîòóôõùúûÇç ]+'; my $o1 = ($a =~ /^($chars)? ([IVX]+) --- .*$/); my $x1 = $1, my $x2 = $2; my $o2 = ($b =~ /^($chars)? ([IVX]+) --- .*$/); my $y1 = $1, my $y2 = $2; if ($o1 && $o2 && ($x1 eq $y1)) { ((&arabic ($x2)) <=> (&arabic ($y2))); } else { $a cmp $b; } } # end of ssort sub arabic { my $x = shift; $x =~ s/([IVXLCDM])(\1*)/$rmnarb{$1}*((length $2)+1).' '/ge; my @x = split / /, $x; while ((scalar @x) > 1) { my $y = ($x[$#x] > $x[$#x-1]) ? $x[$#x] - $x[$#x-1] : $x[$#x] + $x[$#x-1]; splice @x, $#x-1, 2, $y; } join (" ", @x); } # end of arabic sub roman { my $arabic = shift; my $roman; my ($excep_roman, $remainder) = ('', 0); if ($arabic > 0) { ($excep_roman, $remainder) = @{&ranged ($arabic)}; if ($excep_roman ne '') { $roman .= $excep_roman . &roman ($remainder); } else { my $denom = &nearest ($arabic); my $division = $arabic / $denom; $roman .= ($arbrmn{$denom}) x $division . &roman ($arabic % $denom); } } else { ''; } } # end of roman =head1 ESTRUTURAS DE DADOS =over =item B<%dthandler> Array associativo que a função I recebe. =item B<%anthropos_spnames> Array associativo que contem a lista de apelidos --- dos nomes passíveis de surgirem como items no índice toponímico --- que não seguem a I (ver Índice Antroponímico/Regra 1). =item B<%topos> Array associativo que relaciona nomes de cidades, vilas, etc. a lugares e, por sua vez, a bulas em que elas ocorrem (ver Índice Toponímico). =item B<%geotopos> Array associativo que contem informação geográfica específica para cada cidade, vila, etc. (ver Índice Toponímico). =item B<%addgeotopos> Array associativo que contem informação geográfica adicional para cada cidade, vila, etc. (ver Índice Toponímico) =back =cut my %dthandler = ( '-outputenc' => 'ISO-8859-1', #-default => sub { $c; }, # i'd rather specify elements, one by one. -type => {}, -begin => sub { # gerar $bbtoccssfile open BBTOCCSSFH, ">$bbtoccssfile" or die; print BBTOCCSSFH &mkbbtoccss; close BBTOCCSSFH; # gerar $bbctscssfile open BBCTSCSSFH, ">$bbctscssfile" or die; print BBCTSCSSFH &mkbbctscss; close BBCTSCSSFH; # gerar $bbmainfile open BBMFH, ">$bbmainfile" or die; print BBMFH &mkframeset; close BBMFH; #gerar $credits open CREDITSFH, ">$bbcreditsfile" or die; print CREDITSFH &mkcredits; close CREDITSFH; }, bulario => sub { $c = &startHTML . &bbFrontPage . "\n" . $c; }, intro => sub { &toc ('H2', $v{docidx} . " " . $v{title}, "intro", 1) . $c; }, quotation => sub { '' . "\n" . $c . "\n\n" . '
' . "\n" . '(' . "$v{author}, $v{title}, $v{local}, $v{year}, p. $v{page})\n" . ')' . '
' . '
' . "\n\n"; }, block => sub { '

' . "\n" . $c . "\n" . '

' . "\n\n"; }, idxlist => sub { '
' . "\n" . '
    ' . "\n" . $c . "\n" . '
'; }, idxitem => sub { (($idxitem++ > 0) ? &item_separator : "") . '
  • ' . $c . '
  • '; }, synctable => sub { &toc ('H2', $v{docidx} . " " . $v{title}, "synctable", 1) . '' . "\n" . '' . "\n" . $c . '' . "\n" . '
    ' . "\n"; }, archbishops => sub { '' . "\n" . '' . "\n" . '' . $c . '
    ' . '' . $v{title} . '' . '
    ' . "\n". '' . "\n"; }, archbishop => sub { $c = &trim ($c); '' . "\n" . '' . &mk_time (\%v) . '' . "\n" . '' . $c . '' . "\n" . ''; }, popes => sub { '' . "\n" . '' . "\n" . '' . $c . '
    ' . '' . $v{title} . '' . '
    ' . "\n". '' . "\n"; }, pope => sub { $c = &trim ($c); '' . "\n" . '' . &mk_time (\%v) . '' . "\n" . '' . $c . '' . "\n" . ''; }, bibsiglas => sub { &toc ('H2', $v{docidx} . " " . $v{title}, "bibsiglas", 1). "\n" . $c; }, printedrefs => sub { &toc ('H3', $v{docidx} . " " . $v{title}, "printedrefs", 1) . "\n" . '
    ' . "\n" . $c . '
    ' . "\n"; }, printedref => sub { chomp ($v{year}); $v{year} =~ s/\n//; chomp ($c); $c .= $v{year}; }, author => sub { $c =~ s/\n//g; chomp ($c); '
    ' . $c . '
    '; }, docname => sub { chomp ($c); $c =~ s/\n//g; '
    ' . $c . '
    ' . "\n" . '

    ' . "\n"; }, hwrittenrefs => sub { &toc ('H3', $v{docidx} . " " . $v{title}, "hwrittenrefs", 1) . "\n" . '

    ' . "\n" . $c . '

    ' . "\n"; }, hwrittenrefset => sub { (($architem++ > 0) ? &item_separator : "" ) . '

    ' . "$v{archive}" . '

    ' . "\n" . '
      ' . "\n" . $c . '
    ' . "\n"; }, hwref => sub { $c =~ s/\n//; '
  • ' . $c . '
  • ' . '

    '; }, abbsiglas => sub { &toc ('H3', $v{docidx} . " " . $v{title}, "abbsiglas", 1) . "\n" . '' . "\n" . $c . '
    ' . "\n"; }, abbsigla => sub { '' . "\n" . '' . $abb . '' . "\n" . '' . $sigla . '' . "\n" . '' . "\n"; }, abb => sub { chomp ($c); $abb = $c; }, sigla => sub { chomp ($c); $sigla = $c; }, summaries => sub { &toc ('H2', $v{docidx} . " " . $v{title}, "summaries", 1) . "\n" . $c . "\n"; }, century => sub { '

    ' . "\n" . '

    ' . "\n" . &toc ('H3', "$v{title} $v{century}", "century$v{century}", 1) . "\n" . '
    ' . "\n" . '

    ' . "\n" . $c; }, bula => sub { $current_bula_id = $v{id}; '

    ' . "\n" . '' . "\n" . '' . "\n" . '' . "\n" . '' . "\n" . '' . "\n" . '' . "\n" . '
    ' . "\n" . &toc ('H4', &bula_id ($current_bula_id), $current_bula_id, 0) . '' . "\n" . &bula_space_and_time (\%v). "\n" . '' . "\n" . '
    ' . "\n" . '

    ' . "\n" . '

    ' . "\n" . '' . "\n" . "$header --- " . ($v{role} or "BULA") . " " . $content . "\n" . '' . "\n" . '

    ' . "\n" . $c; }, header => sub { $header = "$who $linkage $whoms."; undef $whoms; # reset $whoms ""; }, who => sub { $who = $c; $linkage = (defined $v{link}) ? $v{link} : ' a '; ""; }, whom => sub { chomp ($c); $whoms .= $c; if (defined $v{link}) { chomp ($v{link}); $whoms .= (($v{link} =~ /^,/) ? '' : ' ') . $v{link} . ' '; } ""; }, content => sub { $content = &trim ($c); ""; }, addon => sub { '

    ' . "\n" . $c . '

    ' . "\n"; }, quoted => sub { '"' . &trim ($c) . '"' . '

    ' . "\n"; }, library => sub { chomp ($v{name}); "$v{name} --- $c" . '

    ' . "\n"; }, publ => sub { chomp ($c); "PUBL.: $c" . '

    ' . "\n"; }, ref => sub { chomp ($c); "REF.: $c" . '

    ' . "\n"; }, note => sub { chomp ($c); "NOTA: $c" . '

    ' . "\n"; }, appendix => sub { $v{title} =~ s/\n//g; &toc ('H2', $v{title}, "appendixtitle", 1) . "\n" . $c; }, subtitle => sub { $c =~ s/\n//g; '

    ' . $c . '

    ' . "\n\n"; }, transfbulas => sub { '' . "\n" . '' . "\n" . $c. '
    Ano
    ' . "\n"; }, transfbula => sub { chomp ($v{id}); chomp ($v{year}); chomp ($v{eyear}); $c =~ s/\n//g; '' . "\n" . '' . "$v{id} -- $c" . '' . "\n" . '' . ((not defined $v{year}) ? '......' : (($v{year} and $v{eyear}) ? '' . $v{year} . ' ou ' . $v{eyear} . '' : '' . $v{year} . '')) . '' . "\n" . ''; }, anthropos => sub { chomp ($c); chomp ($v{role}); my $whopos = (defined $v{fullname}) ? (chomp ($v{fullname}), &prepstr ($v{fullname})) : &prepstr ($c); $v{role} = &prepstr ($v{role}); push (@{$anthropos{$whopos}{$v{role}}}, &bula_id ($current_bula_id) + 1); $c; }, topos => sub { chomp ($c); chomp ($v{name}); chomp ($v{role}); chomp ($v{geoinfo}); my $wherepos = (defined $v{contents}) ? (chomp ($v{contents}), uc ($v{contents})) : uc ($c); $v{role} = &prepstr ($v{role}); push (@{$topos{$wherepos}{$v{role}}}, &bula_id ($current_bula_id) + 1); $geotopos{$wherepos} = $v{geoinfo} if ((!exists $geotopos{$wherepos}) && (exists $v{geoinfo}) && ($v{geoinfo} ne '')); $addgeotopos{$wherepos} = $v{name} if ((!exists $addgeotopos{$wherepos}) && (exists $v{name}) && ($v{name} ne '')); $c; }, -end => sub { # pq a função I desordena os nomes das pessoas # (devido à aplicação da regra 1), # é necessário reordenar o seu resultado: my $the_end = $c . &anthroposIndexHeader; $anthropos_or_topos = 'A'; $the_end .= join ("\n
    <\/BR>\n", &apply_initials (sort ssort (split (/\n/, &anthropos)))) . &toposIndexHeader; $anthropos_or_topos = 'T'; $the_end .= join ("\n
    <\/BR>\n", &apply_initials (sort (split (/\n/, &topos)))) . &endHTML; $the_end; }, ); # end of %dthandler structure # processar bb... open BBCFH, ">$bbctsfile" or die; # print BBCFH dtstring (&pre_process ($xmlfile), %dthandler); my $bbcontents = dtstring (&pre_process ($xmlfile), %dthandler); # abrir um descritor para $bbtocfile e escrever # codigo HTML inicial: open BBTOCFH, ">$bbtocfile" or die; print BBTOCFH &init_toc; # escrever o toc propriamente dito: local (undef $/); $_ = $bbcontents; my $yy = ""; $bbcontents =~ s/(.*?)<\/toc>/$yy .= $1 . "\n", ""/sge; print BBTOCFH $yy; # escrever para BBTOCFH código HTML final # e fechar este descritor. print BBTOCFH &end_toc; close BBTOCFH; print BBCFH $bbcontents; close BBCFH; =head2 B A função I gera uma âncora (anchor) com informação de um título de secção no frame do conteúdo do bulário e um link respectivo na tabela de conteúdo. Recebe 4 parâmetros: =over =item $hstyle Estilo a aplicar tanto à âncora como ao link (e.g., "H3") =item $htitle Título de secção =item $anchor Nome da âncora =item $linkstyling Booleano que determina se o link deverá ser ($linkingstyling = 1) ou não ($linkingstyling = 0) estilizado de acordo com a estilização aplicada a ancora. =back =cut sub toc { my ($hstyle, $htitle, $anchor, $linkstyling) = @_; my $to_toc = '' . $htitle . '' . ' '; # stylize or not the link according to $nolinkstyling value: $to_toc = '<' . $hstyle . '>' . $to_toc . '' if ($linkstyling == 1); '<' . $hstyle . '>' . '' . $htitle . '' . '' . "\n\n" . ((($htitle =~ /^[0-9]+$/) and (not defined $bulaidx)) ? "" : ('' . $to_toc . '')); } # end of toc =head2 B A função I devolve uma string representativa do código HTML inicial relativo ao TOC. =cut sub init_toc { <<'INIT_TOC'

    Bulário Bracarense

    Créditos INIT_TOC } # end of init_toc =head2 B A função I devolve uma string representativa do código HTML final relativo ao TOC. =cut sub end_toc { <<'END_TOC' END_TOC } # end of end_toc =head1 ÍNDICES B gera automaticamente os índices toponímico e antroponímico do Bullarium Bracarense. =head2 Índice Antroponímico A lista de apelidos pertencentes a items do índice antroponímico que não seguem a I é carregada para o array associativo B<%anthropos_spnames>. I Seja Nome = um nome de uma pessoa, a sua representação como item do índice antroponímico será: "uc (word[n]), word[1] ... word[n-1]", sendo I a função em Perl que, para uma dada string, devolve uma nova em que todos os seus caracteres estão em maiúsculas. Por exemplo, a representação no índice toponímico de I é I. NB: De referir que não é necessário incluir nesta lista nomes do tipo "CLEMENTE III", uma vez que todos os nomes que seguem esta forma (terminados em letras romanas) são já tratados de forma especial. Os elementos XML I são os que populam as estruturas supra-citadas: Como exemplo, tomem-se o seguinte elemento: Vasco =head2 Índice Toponímico A informação toponímica (relativa a lugares), é guardada em duas estruturas: I<%topos> and I<%geotopos>. O array associativo I<%topos> comporta, como suas chaves, os nomes de cidades, vilas, etc. (1), enquanto que o seu contradomínio é uma outra função finita que relaciona lugares específicos de (1) a um conjunto de bulas onde eles são referidos. Exemplo: %topos = ( 'Monção' => { 'convento' => [1, 2, 3, 4, 5], 'mosteiro de S. Francisco' => [6, 7, 8, 9, 10], }, 'Braga' => { 'Bom Jesus' => [21, 52, 63, 74, 85], ... => [...], }, ... ); O array associativo I<%geotopos> contem, para um subconjunto do domínio de I<%topos>, informação geográfica específica. Exemplo: %geotopos = ( 'Monção' => 'v., c. d. Viana do Castelo', ... => ... ); O array associativo I<%addgeotopos> contem, para um subconjunto do domínio de I<%geotopos>, informação geográfica adicional. %addgeotopos = ( 'Adaúfe' => 'Sta. Maria', ... => ... ); Os elementos XML I são os que populam as estruturas supra-citadas: Como exemplo, tomem-se os seguintes elementos: Monção Monção Adaúfe De referir que os valores dos atributos I e I de um determinado elemento I são herdados para os elementos que a ele se seguem. Por exemplo, no exemplo acima, o segundo elemento herda o valor do atributo I do primeiro elemento. Para efeitos de processamento do Bullarium Bracarense, considera-se a inexistência do atributo I num elemento I como sendo igual à existência daquele atributo com valor vazio. Ou seja, Monção é equivalente a Monção =cut =pod A informação antroponímica (relativa a pessoas) é guardada na seguinte estrutura: %anthropos = ( 'inocencio' => { 'bispo' => [1, 2, 3, 4, 5], 'papa' => [6, 7, 8, 9, 10], 'arcebispo' => [6, 7, 8, 9, 10], '' => [5, 6], }, 'clemente' => { 'arcebispo' => [1, 2, 3, 6, 7, 9, 10], 'papa' => [6, 7, 8], '' => [5, 6], }, ); Para cada pessoa, é associado um conjunto de "papéis" (roles) e a cada um destes "papéis" faz-se corresponder um conjunto de bulas que os referenciam. =head1 FUNÇÕES =head2 B A função I prepara uma dada string para inserção na estrutura I<%anthropos> ou I<%topos>. Eis uma série de imagens da função para um conjunto finitos de nomes de pessoas (as linhas a B são aquelas para as quais a função devolve um valor de saída diferente do de entrada): =over =item prepstr ('Clemente') = 'Clemente' =item B =item prepstr ('dos') = 'dos' =item prepstr ('sOARES') = 'sOARES' =item prepstr ('sOARes') = 'sOARes' =item B =item prepstr ('ALEXANDRE III') = 'ALEXANDRE III' =back =cut sub prepstr { my $ppred = shift; my $prepstr; my @prepwords = split (/ +/, $ppred); if ($prepwords[$#prepwords] =~ /^[IVX]+$/) { $prepstr = uc ($ppred); } else { my $ii = 0; my $iimax = scalar @prepwords; for ($ii = 0; $ii < $iimax; $ii++) { my $iielem = $prepwords[$ii]; $prepwords[$ii] = ucfirst (lc ($prepwords[$ii])) if (($iielem eq (uc ($iielem))) and ($iielem !~ /[IVX]+/)); } $prepstr = join (" ", @prepwords); } $prepstr; } # end of sub prepstr =head2 B A função I recebe uma referência para uma lista de entradas de um índice a adiciona-lhe as iniciais (A, B, C...) antes da sublista de entradas correspondentes. =cut sub apply_initials { my @unapplied = @_; my @applied = (); my $entry; my $current_letter = substr ($unapplied[0], 0, 1); push (@applied, &mkiinitial ($current_letter)); for $entry (@unapplied) { my $first_letter = substr ($entry, 0, 1); if (($first_letter ne $current_letter) and ($first_letter =~ /[A-Z]/)) { $current_letter = $first_letter; push (@applied, &mkiinitial ($current_letter)); } push (@applied, $entry); } @applied; } # end of sub apply_initials =head2 B A função I recebe uma inicial e devolve uma string HTML com a inicial centrada e estilizada (função auxiliar de I). =cut sub mkiinitial { my $theinitial = shift; '
    ' . "\n" . '' . &toc ('H4', $theinitial, $anthropos_or_topos . $theinitial, 0) . '' . "\n" . '
    ' . "\n"; } # end of sub mkiinitial =pod A função I constrói o Índice Antroponímico. Devolve uma string da forma: "APELIDO, Nome --- role, docs. x, y a z APELIDO, Nome --- docs. x, y a z APELIDO, Nome --- role, doc. x ..." =cut sub anthropos { my %roles; my @docs; my $return_value = ""; foreach (sort keys %anthropos) { my $hwho = $_; %roles = %{$anthropos{$hwho}}; local ($\ = ""); foreach (sort keys %roles) { my $a_role = $_; $return_value .= &mkname ($hwho); $return_value .= " --- "; @docs = @{$roles{$_}}; # se a pessoa for apenas referida numa bula, # usa-se 'doc.', senao usa-se 'docs.': my $doc_or_docs = ((scalar @docs) == 1) ? 'doc.' : 'docs.'; $return_value .= ($a_role ne '') ? '' . $a_role . ', ' . ' ' . $doc_or_docs . ' ' : ' ' . $doc_or_docs . ' '; $return_value .= join (", ", &sortandlink (@docs)) . ".\n"; } } $return_value; } # end of sub anthropos =head2 B A função I constrói o Índice Toponímico. =cut sub topos { my %roles; my @docs; my $return_value = ""; foreach my $hwhere (sort keys %topos) { %roles = %{$topos{$hwhere}}; local ($\ = ""); $return_value .= $hwhere; $return_value .= " --- "; $return_value .= $addgeotopos{$hwhere} . ' ' if exists $addgeotopos{$hwhere}; $return_value .= '[' . $geotopos{$hwhere} . ']' . ': ' if exists $geotopos{$hwhere}; my $rcounter = 1; my $rmaxcounter = scalar keys %roles; # a ordenação dentro do mesmo topos está a ser feita por # ordem alfabética ascendente dos nomes das roles; # caso se desejasse ordenar numericamente as bulas tendo em # conta as diferentes roles dentro do mesmo lugar: # foreach (sort {$roles{$a}[0] <=> $roles{$b}[0]} keys %roles) { #} foreach (sort keys %roles) { my $a_role = $_; @docs = @{$roles{$_}}; # se o lugar for apenas referido numa bula, # usa-se 'doc.', senao usa-se 'docs.': my $doc_or_docs = ((scalar @docs) == 1) ? 'doc.' : 'docs.'; $return_value .= ($a_role ne '') ? '' . $a_role . ', ' . ' ' . $doc_or_docs . ' ' : ' ' . $doc_or_docs . ' '; $return_value .= join (", ", &sortandlink (@docs)); $return_value .= ($rcounter++ == $rmaxcounter) ? ".\n" : "; "; } } $return_value; } # end of sub topos =head2 B A função I devolve uma representação apropriada para o nome de uma pessoa para inclusão no índice antroponímico, ou seja, para um dado nome, aplica a I. =cut sub mkname { my $names = shift; chomp ($names); my $anames = ""; my $z = 0; my @spnames = keys %anthropos_spnames; # if a name ends with one of the surnames # defined in %anthropos_spnames... for ($z = 0; $z <= $#spnames && ($anames eq ""); $z++) { my $sp = $spnames[$z]; if ($names =~ /(.*?)$sp/i) { # for example, for "Afonso Castelo Branco", # $anames will be "CASTELO BRANCO, Afonso" $anames = uc ($sp) . (($1 ne '') ? ', ' . $1 : ''); } } # if $anames doesn't end with one of the surnames # defined in %anthropos_spnames... if ($anames eq "") { # first, split up its words... my @names = split (/ +/, $names); # then check if they end in roman, like, # for instance, "Calisto III": if ($names[$#names] =~ /^[IVX]+$/) { # if something like 'CLEMENTE VI', then simply upcase it: $anames = uc (join (" ", @names)); } # if it doesn't end in roman and #words > 1, # then swap surname with rest of words: elsif ((scalar @names) > 1) { $anames = uc ($names[$#names]) . ', ' . (join (' ', @names[0..$#names-1])); } # finally, if number of words is just 1, # simply upcase it: else { $anames = uc ($names); } } $anames; } # end of sub mkname =head2 B A função I recebe um array de números de bulas e devolve uma lista ordenada (pelos números de bulas) de hyperlinks para essas mesmas bulas. Ex.: sortandlink (1, 2, 101) = ('1', '2', '101') =cut sub sortandlink { local ($, = ", "); my @docs = &remove_repeated (sort {$a <=> $b} @_); foreach (@docs) { s!$_!$_!; } @docs; } # end of sub sortandlink =head2 B A função I recebe um array ordenado de escalares e devolve um array ordenado sem elementos repetidos. =cut sub remove_repeated { my @elems = @_; my @rrelems = (); if ((scalar @elems) >= 2) { if ($elems[0] == $elems[1]) { shift (@elems); @elems = &remove_repeated (@elems); } else { unshift (@rrelems, $elems[0]); shift (@elems); push (@rrelems, &remove_repeated (@elems)); @elems = @rrelems; } } @elems; } # end of sub remove_repeated =head2 B A função I recebe o nome de um ficheiro XML e devolve o seu conteúdo subtituídas todas as entidades de caracteres (caracter entities) por caracteres ISO-8859-1. =cut sub pre_process { open FH, $xmlfile or die ($!); local undef $/; $_ = ; $_ =~ s/á/á/g; $_ =~ s/é/é/g; $_ =~ s/í/í/g; $_ =~ s/ó/ó/g; $_ =~ s/ú/ú/g; $_ =~ s/à/à/g; $_ =~ s/è/è/g; $_ =~ s/ì/ì/g; $_ =~ s/ò/ò/g; $_ =~ s/ù/ù/g; $_ =~ s/ç/ç/g; $_ =~ s/ã/ã/g; $_ =~ s/õ/õ/g; $_ =~ s/â/â/g; $_ =~ s/ê/ê/g; $_ =~ s/î/î/g; $_ =~ s/ô/ô/g; $_ =~ s/û/û/g; $_ =~ s/Á/À/g; $_ =~ s/É/É/g; $_ =~ s/Í/Í/g; $_ =~ s/Ó/Ó/g; $_ =~ s/Ù/Ú/g; $_ =~ s/À/À/g; $_ =~ s/È/È/g; $_ =~ s/Ì/Ì/g; $_ =~ s/Ò/Ò/g; $_ =~ s/Ù/Ù/g; $_ =~ s/Ç/Ç/g; $_ =~ s/Ã/Ã/g; $_ =~ s/Õ/Õ/g; $_ =~ s/Â/Â/g; $_ =~ s/Ê/Ê/g; $_ =~ s/Î/Î/g; $_ =~ s/Ô/Ô/g; $_ =~ s/Û/Û/g; $_ =~ s/ª/$^{a}/g; $_ =~ s/º/$^{o}/g; my $t = $_; close FH; $t; } # end of sub pre_process =head2 B A função I recebe um array assoc de atributos (%v) de arcebispos ou papas e devolve uma string de info temporal adequada. =cut sub mk_time { local ($_ = shift); my %attrs = %$_; my $timed; my $sure; $sure = ($attrs{sure} eq 'yes' or not $attrs{sure}) ? 1 : 0; $timed .= $attrs{syear}; if ($attrs{eyear} ne '') { $timed .= '--'.$attrs{eyear};} if (not $sure) { $timed .= "?"; } $timed; } # end of sub mk_time =head2 B A função I recebe um array associativo de atributos de elemento C e devolve uma string de informação espacial/temporal apropriada. =cut sub bula_space_and_time { # Exemplo de um elemento bula: # local ($_ = shift); my %attrs = %$_; my $spacetimed; my $ysure = ($attrs{ysure} eq 'yes' or not $attrs{ysure}) ? 1 : 0; my $dsure = ($attrs{dsure} eq 'yes' or not $attrs{dsure}) ? 1 : 0; my $wsure = ($attrs{wsure} eq 'yes' or not $attrs{wsure}) ? 1 : 0; my $yabout = ($attrs{yabout} eq 'no' or not $attrs{yabout}) ? 1 : 0; $spacetimed .= ''; if (not $ysure) { $spacetimed .= "["; } if (not $yabout) { $spacetimed .= "c. "; } $spacetimed .= $attrs{syear}; if ($attrs{eyear} ne '') { $spacetimed .= '--'.$attrs{eyear};} if (not $ysure) { $spacetimed .= "]"; } $spacetimed .= ''; if ($attrs{month} ne '') { $spacetimed .= ", $attrs{month}"; } # if ($attrs{day} ne '') { $spacetimed .= ", "; } # if (not $dsure) { $spacetimed .= "["; } # if ($attrs{day} ne '') { $spacetimed .= "$attrs{day}"; } # if (not $dsure) { $spacetimed .= "]"; } # # if ($attrs{where} ne '') { $spacetimed .= ", "; } # if (not $wsure) { $spacetimed .= "["; } # if ($attrs{where} ne '') { $spacetimed .= "$attrs{where}"; } # if (not $wsure) { $spacetimed .= "]"; } if ($attrs{day} ne '') { $spacetimed .= ", "; $spacetimed .= (not $dsure) ? "[".$attrs{day}."]" : $attrs{day}; } if ($attrs{where} ne '') { $spacetimed .= ", "; $spacetimed .= (not $wsure) ? "[".$attrs{where}."]" : $attrs{where}; } if ($attrs{sure} eq 'no') { $spacetimed .= ' (?)'; } $spacetimed; } # end of sub bula_space_and_time =head2 B A função I recebe uma string e devolve uma outra similar aquela, mas sem C<\n>s no seu início e fim. =cut sub trim { $_ = shift; s/\n+(.*)\n+/$1/s; $_; } # end of sub trim =head2 B A função I recebe uma string e devolve uma outra similar aquela, mas sem C<\n>s no seu início. =cut sub trim_beginning { $_ = shift; s/\n+(.*)/$1/s; $_; } # end of sub trim_beginning =head2 B A função I recebe uma string da forma B[0-9]+ e devolve a parte [0-9]+. =cut sub bula_id { $_ = shift; s/B([0-9]+)/$1/; $_; } # end of sub bula_id =head2 B A função I devolve código HTML referente ao separador existente entre items da lista enumerada que aparece depois da "Introdução". =cut sub item_separator { "\n\n" . '
    *  *  *
    ' . "\n\n"; } # end of item_separator =head2 B A função I devolve código referente ao bloco inicial típico de um documento HTML. =cut sub startHTML { q| | . $title . q| | } # end of sub startHTML =head2 B A função I devolve código HTML referente ao capítulo "Índices" e à secção "Índice Antroponímico". =cut sub anthroposIndexHeader { &toc ('H2', "ÍNDICES", "indexes", 1) . "\n" . &toc ('H3', "Índice Antroponímico", "anthroposidx", 1) . "\n"; } # end of sub anthroposIndexHeader =head2 B A função I devolve código HTML referente à secção "Índice Toponímico". =cut sub toposIndexHeader { &toc ('H3', "Índice Toponímico", "toposidx", 1) . "\n"; } # end of toposIndexHeader =head2 B A função I devolve código HTML de finalização. =cut sub endHTML { <<'END_HTML' END_HTML } # end of sub endHTML =head2 B A função I devolve código HTML referente à capa do Bullarium Bracarense. =cut sub bbFrontPage { <<'BB_Front_Page'

    MARIA DA ASSUNÇÃO JÁCOME DE VASCONCELOS

    Técnica Superior do ADB/UM


    ANTÓNIO DE SOUSA ARAÚJO

    Bolseiro da Fundação Calouste Gulbenkian




    BULÁRIO BRACARENSE

    Sumários de Diplomas Pontifícios dos Séculos XI a XIX




    Arquivo Distrital de Braga

    Universidade do Minho

    B r a g a

    1 9 8 6

    BB_Front_Page } # end of sub bbFrontPage =head2 B A função I devolve o código HTML que reside no ficheiro principal F<$bbmainfile> e que contem um frameset de cardinalidade 2. =cut sub mkframeset { <<"mkframeset" Bulário Bracarense <!-- This document constains frames...--> mkframeset } # end of mkframeset =head2 B A função I devolve o código HTML que reside no ficheiro principal F<$bbcreditsfile> e que contem informação sobre os créditos. =cut sub mkcredits { <<'mkcredits' Bulário Bracarense - Créditos Voltar ao Índice

    Créditos

    A publicação electrónica do Bulário Bracarense - Sumários de Diplomas Pontifícios dos Séculos XI a XIX - desenvolveu-se no âmbito da disciplina Opção III (Projecto) do 5º ano da Licenciatura em Engenharia de Sistemas e Informática na Universidade do Minho.

    Este projecto, da autoria de José Luís dos Santos, foi supervisionado pelo prof. José Carlos Ramalho e teve a colaboração da Drª Clara Sofia Moreira, do Arquivo Distrital de Braga.

    A obra que aqui se apresenta é uma edição esgotada do ADB e cuja existência se resume a 1000 exemplares que aquela instituição detém, resultantes de uma tiragem efectuada em 1986. Por esta razão, e pelo seu valor historico-cultural reconhecido, a publicação on-line do Bulário Bracarense reveste-se de importância acrescida, quebrando quaisquer restrições de acesso ou de disponibilidade espacio-temporal.

    Que a informação aqui disponibilizada sirva de elemento útil para potenciais investigadores deste tema, ou deste período da História, e que este tipo de iniciativas se continue a promover.

    Santos
    Braga, Setembro de 2000.

    Voltar ao Índice mkcredits } # end of mkcredits =head2 B A função I devolve o conteúdo do ficheiro F<$bbtoccssfile>. =cut sub mkbbtoccss { <<'MKBBTOCCSS' H1 { font-size:17pt; font-style:normal; font-weight:normal; color:#003366 } H2 { font-size:13pt; font-style:normal; font-weight:normal; color:#003366 } H3 { font-size:11pt; font-style:normal; font-weight:normal; color:#003366; margin-left:13pt; display:list-item color:#003366; } H4 { font-size:9pt; font-style:normal; font-weight:normal; color:#003366; margin-left:17pt; background-color: white; display:inline; list-item:12pt; inline-height:5pt; inline-width:5pt; word-spacing:12pt; text-indent:12pt; } H5 { font-size:7pt; font-style:normal; font-weight:normal; color:#003366 } H6 { font-size:5pt; font-style:normal; font-weight:normal; color:#003366 } UL { margin-top=.5em; } LI { margin-bottom: .1em; margin-left: -1em; font-size:12pt; color:#003366; } BODY { BACKGROUND: #FCFCFF } link { text-decoration: none; } a.name { background-color: white; } a:link {color: #003366;} a:active {color: #003366;} a:visited {color: #003366;} a:hover { font-style:normal; font-weight:normal; color:#000000 } MKBBTOCCSS } # end of mkbbtoccss =head2 B A função I devolve o conteúdo do ficheiro F<$bbctscssfile>. =cut sub mkbbctscss { <<'MKBBCTSCSS' H1 { font-style:italic; font-weight:bold; color:#003366 } H2 { font-style:italic; font-weight:bold; color:#003366 } H3 { font-style:italic; font-weight:bold; color:#003366 } H4 { font-style:italic; font-weight:bold; color:#003366 } H5 { font-style:italic; font-weight:bold; color:#003366 } H6 { font-style:italic; font-weight:bold; color:#003366 } BODY { BACKGROUND: #FCFCFF } table { font-size: 90%; cellspacing: 0; cellpadding: 3; bordercolor: #DDDDDD; frame: below; rules: rows; } th { text-align: left; background: #DDDDDD; vertical-align: top; } tr { vertical-align: top; } td { margin: .025em; vertical-align: top; align: left;} p { margin-top: .6em; margin-bottom: .6em;} MKBBCTSCSS } # end of mkbbctscss =head2 B A função I que devolve a lista de apelidos pertences a items do índice antroponímico que I seguem a regra 1. =cut sub load_anthspnames { local (undef $/); $_ = ; # read everything between and /(.*?)<\/anthspnames>/s; # build array of anthspnames my @anthspnames = split /\n/, $1; # return hash of $_ => 1 ($_ = each anthspname) elements # without empty keys (i.e., with no empty $_) map { ($_ ne '') ? ($_ => 1) : () } @anthspnames; } # end of load_anthspnames =head1 FICHEIROS =over =item F DTD do Bullarium Bracarense =back =cut =head1 REFERÊNCIAS =over =item B Tradutor do Bullarium Bracarense de XML para LaTeX. =item B O melhor módulo Perl de processamento de documentos XML, escrito pelo Mestre José João Almeida . =back =cut =head1 AUTOR Santos, José Luís =cut __END__ # Lista de apelidos pertencentes a items que surgem no índice # antroponímico que NÃO DEVEM seguir a regra normal: # APELIDO, Outras palavras, # em que APELIDO representa a última palavra do nome em maiúsculas. # NB: De referir que nãe é necessário incluir nesta lista nomes # do tipo "CLEMENTE III", uma vez que todos os nomes que seguem # esta forma (terminados em letras romanas) são já tratados de forma # especial. Afonso Esteves de Azambuja Afonso Mendes Afonso de Brito Agostinho de Jesus António Pereto Bartolomeu dos Mártires Castelo Branco Des Prez Diogo Gelmires Domingos Domingues Durão Lourenço Egas Martins Gaspar da Encarnação Geraldo Domingues Gonçalo Pereira Gonçalo Peres Gonçalo Velho Guilherme Folquini Hugo de Mirabela J. Martim Pais J. Peres Jacob de Sirano Lourenço Martins de Vilela M. Angotes Martinho Fernandes Martinho Geraldes Martinho de Oliveira Martins de Soalhães Mateus Visconti Maurício Burdino Miguel Pires Miguel Vivas Miguel de Cesena Nicolau Hispano P. Soeiro Paio Mendes Pedro Anes Pedro Anes da Lagiosa Pedro Martins Pedro Salvador Pedro Soares Raimundo Ebrard I S. Paes Solerio Erfordense Sá Pedro São Geraldo Vasco Lourenço Vasco Martins Vasco Rodrigues Vila Verde Álvaro Fernandes