<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Codi |</title><link>https://clementgodbarge.com/ca/code/</link><atom:link href="https://clementgodbarge.com/ca/code/index.xml" rel="self" type="application/rss+xml"/><description>Codi</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>ca</language><image><url>https://clementgodbarge.com/media/icon_hu_64a6c3bec25b3d7b.png</url><title>Codi</title><link>https://clementgodbarge.com/ca/code/</link></image><item><title>tei-mcp</title><link>https://clementgodbarge.com/ca/code/tei-mcp/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ca/code/tei-mcp/</guid><description>&lt;h2 id="tei-mcp-la-tei-p5-per-als-agents-dia"&gt;tei-mcp: la TEI P5 per als agents d’IA&lt;/h2&gt;
&lt;p&gt;tei-mcp és un servidor
de codi obert que dona als assistents de programació amb IA accés directe a l’especificació
. En lloc de refiar-se del que recorda de l’entrenament – cosa que sovint produeix un marcatge plausible però incorrecte –, la IA pot consultar l’especificació en temps real.&lt;/p&gt;
&lt;h2 id="funcions"&gt;Funcions&lt;/h2&gt;
&lt;p&gt;El servidor analitza l’ODD de la TEI P5 i exposa 16 eines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Consultar&lt;/strong&gt; qualsevol element, classe, macro o mòdul pel nom, sense distingir majúscules i amb suggeriments en cas d’errata&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resoldre atributs&lt;/strong&gt; al llarg de tota la jerarquia de classes de la TEI (locals i heretats)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expandir models de contingut&lt;/strong&gt; en arbres estructurats, amb resolució de classes i macros&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validar la imbricació&lt;/strong&gt; – relació directa pare-fill o accessibilitat recursiva, amb seguiment del camí&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validar documents&lt;/strong&gt; segons la TEI P5: models de contingut, atributs, llistes de valors tancades, integritat de les referències i avisos d’obsolescència&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validar elements individuals&lt;/strong&gt; per a fluxos d’edició incremental&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Carregar personalitzacions ODD&lt;/strong&gt; per restringir l’esquema al subconjunt propi d’un projecte&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cercar&lt;/strong&gt; en tots els tipus d’entitat amb expressions regulars&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="installació"&gt;Instal·lació&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;O bé executar-lo directament amb:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx tei-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ús"&gt;Ús&lt;/h2&gt;
&lt;p&gt;Afegeix-lo a qualsevol client compatible amb MCP (Claude, Cursor, Windsurf, etc.):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tei&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;uvx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tei-mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El codi font i la documentació són al
.&lt;/p&gt;</description></item><item><title>Multi-Saxon</title><link>https://clementgodbarge.com/ca/code/multi-saxon/</link><pubDate>Fri, 28 Mar 2025 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ca/code/multi-saxon/</guid><description>&lt;h2 id="multi-saxon-processament-xslt-en-parallel-per-a-grans-corpus-tei"&gt;Multi-Saxon: processament XSLT en paral·lel per a grans corpus TEI&lt;/h2&gt;
&lt;p&gt;Multi-Saxon cobreix un buit important en les eines de processament XML: permet executar en paral·lel transformacions XSLT 2.0 i 3.0 que LXML (una biblioteca XML molt popular en Python) no pot gestionar. Dissenyat expressament per a grans col·leccions de documents XML TEI, Multi-Saxon accelera notablement el processament gràcies a una execució paral·lela eficient.&lt;/p&gt;
&lt;h2 id="característiques-principals"&gt;Característiques principals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Suport XSLT avançat&lt;/strong&gt;: processa transformacions XSLT 2.0 i 3.0 fora de l’abast de LXML&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Processament en paral·lel&lt;/strong&gt;: redueix dràsticament el temps de transformació de grans col·leccions de documents gràcies a la paral·lelització&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimitzat per a TEI&lt;/strong&gt;: dissenyat específicament per a documents XML de la Text Encoding Initiative (TEI)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rendiment escalable&lt;/strong&gt;: gestiona amb eficiència corpus de centenars a milers de documents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiplataforma&lt;/strong&gt;: funciona en sistemes operatius i entorns diversos&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="el-problema-que-resol-multi-saxon"&gt;El problema que resol Multi-Saxon&lt;/h2&gt;
&lt;p&gt;Els investigadors en humanitats digitals que treballen amb TEI topen sovint amb dos obstacles importants:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;LXML (una biblioteca habitual de processament XML en Python) només admet XSLT 1.0, cosa que impedeix fer servir les funcions més avançades d’XSLT 2.0/3.0&lt;/li&gt;
&lt;li&gt;Processar seqüencialment grans corpus de documents TEI pot ser prohibitivament lent&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Multi-Saxon resol tots dos problemes aprofitant les capacitats XSLT avançades de Saxon i repartint el processament entre diversos nuclis, amb guanys de rendiment considerables.&lt;/p&gt;
&lt;h2 id="implementació"&gt;Implementació&lt;/h2&gt;
&lt;p&gt;Multi-Saxon combina Python amb el processador Saxon de Java per crear un flux de transformació d’alt rendiment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fa servir la biblioteca Saxon de Java per a un processament robust d’XSLT 2.0/3.0&lt;/li&gt;
&lt;li&gt;Implementa el multiprocessament per distribuir les transformacions entre els nuclis de CPU disponibles&lt;/li&gt;
&lt;li&gt;Gestiona eficientment els grups de processos per maximitzar el rendiment&lt;/li&gt;
&lt;li&gt;Ofereix una interfície senzilla per processar documents TEI per lots&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="exemple-dús"&gt;Exemple d’ús&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;multi_saxon&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MultiSaxon&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Initialize with your XSLT stylesheet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transformer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MultiSaxon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;transform.xsl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Transform a single document&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transformer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input.xml&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output.xml&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Transform an entire directory in parallel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transformer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform_directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="impacte-per-a-les-humanitats-digitals"&gt;Impacte per a les humanitats digitals&lt;/h2&gt;
&lt;p&gt;Per als projectes d’humanitats digitals que treballen amb grans col·leccions de documents TEI, Multi-Saxon fa possible:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transformacions complexes a escala de tot el corpus que serien impossibles amb LXML&lt;/li&gt;
&lt;li&gt;Temps de processament dràsticament reduïts (sovint entre 5 i 10 vegades més ràpid en sistemes multinucli)&lt;/li&gt;
&lt;li&gt;Anàlisis més sofisticades gràcies a les funcions avançades d’XSLT 2.0/3.0&lt;/li&gt;
&lt;li&gt;Un flux de treball més senzill per processar col·leccions senceres de documents&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El codi font i la documentació són al
.&lt;/p&gt;</description></item><item><title>persNamer</title><link>https://clementgodbarge.com/ca/code/persnamer/</link><pubDate>Fri, 28 Mar 2025 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ca/code/persnamer/</guid><description>&lt;h2 id="persnamer-connectar-la-tei-amb-el-virtual-international-authority-file"&gt;persNamer: connectar la TEI amb el Virtual International Authority File&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;persNamer és una eina especialitzada en Python que facilita la integració en documents TEI XML de dades d’autoritat sobre persones procedents del VIAF (Virtual International Authority File). En convertir els identificadors VIAF en marcatge TEI a punt per fer servir, persNamer redueix notablement la feina manual que comporta crear entrades de persona estructurades per a les edicions acadèmiques digitals.&lt;/p&gt;
&lt;h2 id="el-repte-del-control-dautoritats-en-tei"&gt;El repte del control d’autoritats en TEI&lt;/h2&gt;
&lt;p&gt;Les edicions acadèmiques digitals sovint exigeixen identificar amb precisió els personatges històrics, incloent-hi els seus noms normalitzats i les dates de naixement i mort. Mantenir un control d’autoritats coherent en tot un projecte requereix:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identificar les persones en els textos històrics&lt;/li&gt;
&lt;li&gt;Trobar-ne dades d’autoritat&lt;/li&gt;
&lt;li&gt;Crear entrades TEI correctament formatades&lt;/li&gt;
&lt;li&gt;Garantir referències coherents al llarg de tot el projecte&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Aquests passos solen ser manuals, lents i propensos a la incoherència.&lt;/p&gt;
&lt;h2 id="com-funciona-persnamer"&gt;Com funciona persNamer&lt;/h2&gt;
&lt;p&gt;persNamer automatitza aquest flux de treball:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Obté les dades del VIAF&lt;/strong&gt;: a partir d’un identificador VIAF, l’eina recupera les dades RDF mitjançant negociació de contingut HTTP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;N’extreu la informació clau&lt;/strong&gt;: analitza l’RDF per extreure’n el nom preferit, la data de naixement i la data de mort&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Genera el marcatge TEI&lt;/strong&gt;: crea dos fragments XML essencials:
&lt;ul&gt;
&lt;li&gt;Una &lt;strong&gt;entrada de fitxer d’autoritats&lt;/strong&gt; (element &lt;code&gt;&amp;lt;person&amp;gt;&lt;/code&gt; amb un &lt;code&gt;xml:id&lt;/code&gt; generat, &lt;code&gt;&amp;lt;persName&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;birth&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;death&amp;gt;&lt;/code&gt; i &lt;code&gt;&amp;lt;idno type=&amp;quot;VIAF&amp;quot;&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;etiqueta d’anotació&lt;/strong&gt; a part (&lt;code&gt;&amp;lt;persName&amp;gt;&lt;/code&gt; amb un atribut &lt;code&gt;ref&lt;/code&gt; que apunta a l’entrada d’autoritat)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Aquesta doble sortida permet als editors mantenir un fitxer d’autoritats centralitzat i, alhora, inserir fàcilment etiquetes d’anotació en els seus textos TEI.&lt;/p&gt;
&lt;h2 id="característiques-principals"&gt;Característiques principals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generació d’identificadors normalitzats&lt;/strong&gt;: crea identificadors XML coherents amb el format &lt;code&gt;pers-[familyname]-[givenname initial]&lt;/code&gt; (p. ex., &lt;code&gt;pers-deteligny-c&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anàlisi d’RDF&lt;/strong&gt;: fa servir &lt;code&gt;rdflib&lt;/code&gt; per extreure informació de diverses propietats RDF (p. ex., &lt;code&gt;rdfs:label&lt;/code&gt;, &lt;code&gt;schema:name&lt;/code&gt;, &lt;code&gt;viaf:mainHead&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interfície de línia d’ordres&lt;/strong&gt;: s’executa amb un número VIAF com a únic argument obligatori&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sortida detallada&lt;/strong&gt;: proporciona informació detallada del processament juntament amb l’XML final&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="exemple-dús"&gt;Exemple d’ús&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python persNamer.py &lt;span class="m"&gt;314802260&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aquesta ordre produeix:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;person&lt;/span&gt; &lt;span class="na"&gt;xml:id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;pers-deteligny-c&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;persName&amp;gt;&lt;/span&gt;Charles deTéligny&lt;span class="nt"&gt;&amp;lt;/persName&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;birth&amp;gt;&lt;/span&gt;1535&lt;span class="nt"&gt;&amp;lt;/birth&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;death&amp;gt;&lt;/span&gt;1572-08-24&lt;span class="nt"&gt;&amp;lt;/death&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;idno&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;VIAF&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;314802260&lt;span class="nt"&gt;&amp;lt;/idno&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/person&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;persName&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;#pers-deteligny-c&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Charles deTéligny&lt;span class="nt"&gt;&amp;lt;/persName&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="aplicacions-en-humanitats-digitals"&gt;Aplicacions en humanitats digitals&lt;/h2&gt;
&lt;p&gt;persNamer és especialment útil per a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Edicions acadèmiques digitals que requereixen control d’autoritats&lt;/li&gt;
&lt;li&gt;Projectes de codificació TEI que treballen amb personatges històrics&lt;/li&gt;
&lt;li&gt;Iniciatives de dades enllaçades que connecten documents amb registres d’autoritat&lt;/li&gt;
&lt;li&gt;Garantir la coherència en grans corpus TEI&lt;/li&gt;
&lt;li&gt;Ensenyar els conceptes del control d’autoritats en cursos d’humanitats digitals&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="implementació"&gt;Implementació&lt;/h2&gt;
&lt;p&gt;persNamer està escrit en Python i depèn de:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;requests&lt;/code&gt; per a les peticions HTTP&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rdflib&lt;/code&gt; per a l’anàlisi d’RDF&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lxml&lt;/code&gt; per a la gestió de l’XML&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El codi font i la documentació són al
.&lt;/p&gt;</description></item><item><title>Emulador de telègraf ITA2</title><link>https://clementgodbarge.com/ca/code/baudot-emulator/</link><pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/ca/code/baudot-emulator/</guid><description>&lt;p&gt;Aquest emulador de l’ITA2 és una eina docent pràctica: fa visibles i interactius uns conceptes de codificació que d’entrada són abstractes. Quan els estudiants escriuen un text i el veuen convertir-se a l’instant en patrons de forats, aprenen alhora diversos conceptes clau de la informàtica i de les telecomunicacions.&lt;/p&gt;
&lt;h2 id="beneficis-pedagògics"&gt;Beneficis pedagògics&lt;/h2&gt;
&lt;p&gt;En primer lloc, mostra la representació binària, és a dir, com un text es converteix en seqüències d’uns i de zeros. Sovint ho ensenyem de manera abstracta; veure aparèixer els forats de debò ajuda els estudiants a entendre com un sistema físic pot representar informació digital.&lt;/p&gt;
&lt;div class="baudot-emulator"&gt;
&lt;h2&gt;ITA2 (Baudot-Murray) Telegraph Type Emulator&lt;/h2&gt;
&lt;p&gt;Type a word in the input below to see its representation on the ITA2 tape.&lt;/p&gt;
&lt;div class="baudot-controls"&gt;
&lt;label for="baudot-input"&gt;Type word:&lt;/label&gt;
&lt;input id="baudot-input" class="text-input" size="50" maxlength="50" /&gt;
&lt;button type="button" id="baudot-ltr-button" class="control-button active"&gt;LTR&lt;/button&gt;
&lt;button type="button" id="baudot-fig-button" class="control-button"&gt;FIG&lt;/button&gt;
&lt;/div&gt;
&lt;div class="tape-outer-container"&gt;
&lt;div class="tape-container"&gt;
&lt;table&gt;
&lt;tbody id="baudot-tape"&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.baudot-emulator {
--light-color: #f3f4f6;
--dark-color: #1f2937;
--light-alt-color: #e5e7eb;
--dark-alt-color: #374151;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
max-width: 100%;
margin: 2rem 0;
padding: 0;
box-sizing: border-box;
}
.baudot-emulator {
--tape-bg: var(--light-color);
--hole-bg: var(--light-color);
--hole-border: #d1d5db;
--punched-bg: var(--dark-color);
--punched-border: var(--dark-color);
--sprocket-bg: var(--light-color);
--sprocket-border: #9ca3af;
--button-bg: var(--light-color);
--button-bg-active: #d1d5db;
--button-text: var(--dark-color);
--button-border: #d1d5db;
--input-bg: white;
--input-border: #d1d5db;
--input-text: var(--dark-color);
--line-number: #6b7280;
}
html.dark .baudot-emulator,
html[data-theme='dark'] .baudot-emulator,
body.dark .baudot-emulator {
--tape-bg: var(--dark-alt-color);
--hole-bg: var(--dark-alt-color);
--hole-border: #4b5563;
--punched-bg: var(--light-color);
--punched-border: var(--light-color);
--sprocket-bg: var(--dark-alt-color);
--sprocket-border: #9ca3af;
--button-bg: var(--dark-alt-color);
--button-bg-active: #4b5563;
--button-text: var(--light-color);
--button-border: #4b5563;
--input-bg: var(--dark-alt-color);
--input-border: #4b5563;
--input-text: var(--light-color);
--line-number: #9ca3af;
}
.baudot-controls {
margin-bottom: 1.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
}
.baudot-emulator .text-input {
flex: 1;
min-width: 200px;
padding: 0.5rem;
font-size: 1rem;
border: 1px solid var(--input-border);
border-radius: 4px;
background: var(--input-bg);
color: var(--input-text);
}
.baudot-emulator .control-button {
padding: 0.5rem 1rem;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid var(--button-border);
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.baudot-emulator .control-button.active {
background: var(--button-bg-active);
font-weight: bold;
}
.tape-outer-container {
padding: 0;
margin-bottom: 1.5rem;
border-radius: 4px;
overflow: hidden;
}
.tape-container {
width: 100%;
overflow-x: auto;
background: var(--tape-bg);
padding: 1rem 0.5rem;
}
.baudot-emulator table {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
border: none;
}
.baudot-emulator tr {
height: 24px;
border: none;
}
.baudot-emulator td {
border: none;
padding: 0;
}
.baudot-emulator .line-number {
width: 20px;
text-align: center;
color: var(--line-number);
font-size: 0.8rem;
padding: 0 8px 0 0;
font-weight: bold;
}
.baudot-emulator .cell {
position: relative;
width: 20px;
height: 20px;
}
.baudot-emulator .cell-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--hole-bg);
border: 1px solid var(--hole-border);
}
.baudot-emulator .punched .cell-content {
background: var(--punched-bg);
border: 1px solid var(--punched-border);
}
.baudot-emulator .sprocket-hole {
position: absolute;
left: 50%;
top: 100%;
transform: translate(-50%, -50%);
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--sprocket-bg);
border: 1px solid var(--sprocket-border);
z-index: 2;
}
&lt;/style&gt;
&lt;script&gt;
document.addEventListener('DOMContentLoaded', function() {
initBaudotEmulator();
});
function initBaudotEmulator() {
if (!document.getElementById('baudot-input')) return;
const textInput = document.getElementById('baudot-input');
const tape = document.getElementById('baudot-tape');
const ltrButton = document.getElementById('baudot-ltr-button');
const figButton = document.getElementById('baudot-fig-button');
const ita2Code = {
'A': '00011', 'B': '11001', 'C': '01110', 'D': '01001', 'E': '00001',
'F': '01101', 'G': '11010', 'H': '10100', 'I': '00110', 'J': '01011',
'K': '01111', 'L': '10010', 'M': '11100', 'N': '01100', 'O': '11000',
'P': '10110', 'Q': '10111', 'R': '01010', 'S': '00101', 'T': '10000',
'U': '00111', 'V': '11110', 'W': '10011', 'X': '11101', 'Y': '10101',
'Z': '10001',
'1': '00011', '2': '11001', '3': '01110', '4': '01001', '5': '00001',
'6': '01101', '7': '11010', '8': '10100', '9': '01011', '0': '11000',
'-': '00011', '?': '00100', ':': '01010', '(': '11000', ')': '11101',
'.': '01000', ',': '00010', "'": '10001', '=': '01111', '/': '10011',
'+': '11011', ' ': '00100',
'FIG': '11011', 'LTR': '11111',
};
function generateTape() {
let rows = '';
for (let row = 0; row &lt; 5; row++) {
rows += '&lt;tr&gt;';
rows += `&lt;td class="line-number"&gt;${row + 1}&lt;/td&gt;`;
for (let col = 0; col &lt; 50; col++) {
rows += `&lt;td id="baudot_${row}_${col}" class="cell unpunched"&gt;
&lt;div class="cell-content"&gt;&lt;/div&gt;
${row === 2 ? '&lt;div class="sprocket-hole"&gt;&lt;/div&gt;' : ''}
&lt;/td&gt;`;
}
rows += '&lt;/tr&gt;';
}
tape.innerHTML = rows;
}
function updateITA2Code(word) {
clearTape();
word = word.toUpperCase();
let tapePosition = 0;
let currentCharType = 'LTR';
ltrButton.classList.add('active');
figButton.classList.remove('active');
for (let i = 0; i &lt; word.length; i++) {
const char = word[i];
let code = ita2Code[char] || ita2Code[' '];
let requiredCharType = /[A-Z ]/.test(char) ? 'LTR' : 'FIG';
if (requiredCharType !== currentCharType) {
const shiftCode = requiredCharType === 'LTR' ? ita2Code['LTR'] : ita2Code['FIG'];
punchTape(shiftCode, tapePosition++);
currentCharType = requiredCharType;
ltrButton.classList.toggle('active', currentCharType === 'LTR');
figButton.classList.toggle('active', currentCharType === 'FIG');
}
punchTape(code, tapePosition++);
}
}
function punchTape(code, tapePosition) {
if (tapePosition &gt;= 50) return;
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${tapePosition}`);
if (cell) {
cell.className = code[bit] === '1' ? 'cell punched' : 'cell unpunched';
}
}
}
function clearTape() {
for (let i = 0; i &lt; 50; i++) {
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${i}`);
if (cell) {
cell.className = 'cell unpunched';
}
}
}
}
generateTape();
textInput.addEventListener('input', function() {
updateITA2Code(this.value);
});
ltrButton.addEventListener('click', function() {
this.classList.add('active');
figButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
figButton.addEventListener('click', function() {
this.classList.add('active');
ltrButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
if (textInput.value) {
updateITA2Code(textInput.value);
}
}
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;El mecanisme de canvi LLETRES/XIFRES introdueix les màquines d’estats de manera natural. Tot experimentant, els estudiants descobreixen que un mateix patró pot representar caràcters diferents segons el mode actiu. Aquesta experiència directa amb la codificació basada en estats els prepara per a conceptes informàtics més complexos.&lt;/p&gt;
&lt;h2 id="detalls-dimplementació"&gt;Detalls d’implementació&lt;/h2&gt;
&lt;p&gt;L’emulador està escrit en JavaScript i HTML/CSS, de manera que es pot incrustar fàcilment en qualsevol pàgina web. El codi és modular i es pot adaptar a contextos educatius diversos.&lt;/p&gt;
&lt;p&gt;Pots consultar el codi font i provar l’emulador tu mateix al
.&lt;/p&gt;</description></item></channel></rss>