Ir para o conteúdo principal
Background Image

Como migrei 31 artigos do LinkedIn para o Hugo com a ajuda do Gemini-CLI

·8 minutos·
Rafael Issao
Autor
Rafael Issao
Apaixonado por tecnologia, programação e inovação. Adoro compartilhar conhecimento e aprender coisas novas todos os dias.
Tabela de conteúdos

Recentemente, decidi que era hora de trazer meus artigos do LinkedIn para o meu blog pessoal, construído com Hugo. A ideia era simples: centralizar meu conteúdo e ter mais controle sobre ele. O que eu não esperava era o tamanho do desafio: 31 artigos para migrar, cada um com suas particularidades.

Neste artigo, vou compartilhar como enfrentei essa migração, as dificuldades que encontrei e como o gemini-cli foi uma ferramenta fundamental para automatizar o processo e me poupar horas de trabalho manual.

Por que migrei do LinkedIn para o blog?
#

A decisão de mover meus artigos do LinkedIn para o meu blog pessoal não foi por acaso. A comparação abaixo ilustra as principais razões para essa mudança:

CaracterísticaLinkedIn ArticlesHugo + Blowfish (Blog Pessoal)
Formatação de CódigoDesafiadora, frequentemente exige imagens.Fácil, com destaque de sintaxe e importação de código.
Organização de ArtigosLimitada (agrupamento, tags).Robusta, com categorias, tags e séries.
Controle de AparênciaRestrito.Total, personalização completa do layout e estilo.
Recursos AdicionaisBásico (likes, comentários).Flexível (diagramas, gráficos, likes, comentários, etc.).
Base TecnológicaPlataforma proprietária.Markdown, estático, leve e rápido.

O desafio: 31 Artigos em HTML
#

O primeiro grande obstáculo era o formato: artigos em HTML para um blog em Markdown. Além disso, enfrentei os seguintes problemas:

  • Código como Imagem: Snippets de código estavam em imagens (via carbon), precisando ser extraídos, hospedados no GitHub e importados no Markdown para serem copiáveis.
  • Download de Imagens: Imagens precisavam ser baixadas e organizadas na estrutura do Hugo, evitando dependência do LinkedIn.
  • Metadados: Extração de título, data de criação e publicação para o front matter do Hugo.

Fazer tudo isso manualmente para 31 artigos seria um trabalho tedioso e propenso a erros. Foi aí que decidi criar um plano e pedir a ajuda do gemini-cli.

Como criei o plano de migração
#

Para garantir um processo consistente e automatizado, resolvi detalhar os passos no GEMINI.md.

Este arquivo é utilizado pelo gemini-cli como parte do próprio contexto.

E para detalhar o plano, primeiro fiz duas migrações de artigos, passo a passo com gemini-cli.

Para cada passo feito com sucesso, eu pedia para o gemini-cli documentar o passo feito no arquivo GEMINI.md.

O plano resultante foi este:

  1. Ler o Conteúdo HTML
  2. Extrair Metadados
  3. Construir o Front Matter
  4. Converter HTML para Markdown
  5. Baixar as Imagens: Se a imagem continha código, extrair o código e inserir o código em um projeto separado.
  6. Gerenciar Contexto de Diretórios: Utilizar a capacidade do gemini-cli de adicionar diretórios ao contexto para gerenciar o projeto de exemplos de código (code-examples) separadamente.

O Desafio Especial: Código em Imagens
#

A parte mais interessante do processo foi lidar com os snippets de código que estavam em formato de imagem. Para resolver isso, fui atrás de uma ferramenta que realizava OCR.

E a partir desta ferramenta, pedi simplesmente pro gemini-cli utilizá-lo para extrair textos de imagens.

O passo a passo desta etapa ficou assim:

  1. OCR (Reconhecimento Óptico de Caracteres): Usar o Tesseract OCR para extrair o texto de cada imagem de código.
  2. Limpeza e Formatação: O texto extraído pelo OCR nem sempre é perfeito. Era preciso revisar, corrigir erros e formatar o código corretamente.
  3. Hospedagem do Código: Para manter o código organizado e reutilizável, criei um projeto separado no GitHub (code-examples) para hospedar todos os snippets de código.
  4. Usar o codeimporter: Finalmente, no arquivo Markdown do post, em vez de um bloco de código, eu usaria o shortcode codeimporter do tema Blowfish para importar o código diretamente do repositório no GitHub.

Resultado final do GEMINI.md
#

Esse arquivo foi gerado pelo gemini-cli iterativamente:

## Use shortcode where possible

- **Available Shortcode** https://blowfish.page/docs/shortcodes/

## Agent Instructions

- **Check URLs:** Always check any URLs provided within this `GEMINI.md` file for additional context, documentation, or specific instructions relevant to the task.
- **Delete after review:** After the user reviews and approves an article migration, delete the original HTML file.

### Article Migration Process

To migrate an article from an HTML file (e.g., from `linkedin-articles/Articles/`) to a Hugo Markdown post (`content/posts/`):

1.  **Read Full HTML Content:** Use `run_shell_command` with `cat` to read the _entire_ HTML file content.
    - Example: `cat /path/to/article.html`
2.  **Extract Metadata:**
    - **Title:** From `<title>` tag or `<h1>` tag.
    - **Created Date:** From `<p class="created">` (format `YYYY-MM-DD`).
    - **Published Date (lastmod):** From `<p class="published">` (format `YYYY-MM-DD`). If not available, use the created date.
    - **Categories/Tags:** Infer from the article content.
3.  **Construct Front Matter:** Create a minimal YAML front matter block:
    ```yaml
    ---
    title: "Extracted Title"
    date: YYYY-MM-DD (Created Date)
    lastmod: YYYY-MM-DD (Published Date or Created Date)
    categories: ["Category1", "Category2"]
    draft: false
    ---
    ```
4.  **Download Images:** For each `<img>` tag, download the image to the post folder. **Do not download the featured image.**
    - Example: `curl -o /path/to/post/image1.png "image_url"`
5.  **Convert HTML Body to Markdown:**
    - Exclude any "Axuda-me DEV!" or "Axuda-me QA!" series logos/descriptions.
    - Convert `<h1>` to `#`, `<h2>` to `##`, `<h3>` to `###`.
    - Convert `<p>` to paragraphs.
    - Convert `<ul>`, `<li>` to Markdown lists.
    - Convert `<blockquote>` to Markdown blockquotes.
    - Convert `<hr>` to `---`.
    - Convert `<a>` to `[link text](url)`.
    - Handle `<pre>` tags: If they contain code, wrap them in ` ```language` (e.g., ` ```gherkin`). If empty, remove them.
    - Images: Convert `<img>` tags to `< figure src="image.png" alt="Alt text" caption="Caption text" >`. If an image contains code, follow the process in the **Code Snippet Management for Articles** section.
6.  **Create New Post File:**
    - Determine a slugified folder name from the title (e.g., "My Article Title" -> `my-article-title`).
    - Create the file at `content/posts/slugified-title/index.md`.
7.  **Write Content:** Write the constructed front matter followed by the converted Markdown content to the new file.
8.  **Review and Refine:** Manually review the generated Markdown for any conversion errors or formatting issues.

### Code Snippet Management for Articles

When an article contains code snippets embedded in images, follow these steps to extract, organize, and display them using the `codeimporter` shortcode:

0. **Detect if the image is a code snippet**

1. **Extract Code from Images (OCR):**

   - Use Tesseract OCR to extract text from the image files.
   - Example: `tesseract /path/to/image.png stdout`

2. **Clean and Format Extracted Code:**

   - Review the Tesseract output and manually clean any artifacts (e.g., line numbers, OCR errors, incorrect characters).
   - Correct syntax, add necessary imports, and ensure proper indentation.

3. **Organize Code in a Separate Project:**

   - Create a dedicated project (e.g., `code-examples`) to host the code snippets.
   - Within this project, create a package structure that reflects the article's date and the image number for each code snippet.
   - Example package structure: `br.com.youready.article.d_YYYY_MM_DD.imageN`
   - Ensure the package declaration in each Java/Groovy file matches its directory structure.
   - Set class visibility: The main class (e.g., `OrderProcessor`, `OrderSpec`) that will be directly imported should be `public`. Helper classes (e.g., `Order`, `Item`) used only within that specific snippet's context should be package-private (remove the `public` keyword).

4. **Host the Code:**

   - Push the `code-examples` project to a public repository (e.g., GitHub).
   - Obtain the raw URL for each code file.

5. **Update Hugo Article (`index.md`):**

   - In the `content/posts/your-article/index.md` file, replace the `figure` shortcode (or any direct code block) with the Blowfish `codeimporter` shortcode.
   - Use the raw URL of the hosted code file and specify the language type.

Minha opinião sincera sobre o uso do gemini-cli
#

Com o plano detalhado no GEMINI.md, eu pude instruir o gemini-cli a executar cada uma dessas etapas.

Mesmo que eu perdesse o contexto após horas de uso, era fácil de recomeçar.

Ele leu o arquivo de instruções e começou a trabalhar, migrando um artigo de cada vez.

O gemini-cli foi capaz de ler os arquivos HTML, extrair os metadados, baixar as imagens, converter o conteúdo para Markdown e até mesmo orquestrar o processo de OCR para os snippets de código.

Claro, o processo não foi 100% automático. Eu precisei revisar cada artigo migrado para garantir que a formatação estivesse correta e que o código extraído pelo OCR estivesse limpo. Mas a maior parte do trabalho pesado foi feita pelo gemini-cli, o que me economizou um tempo enorme.

Algumas das falhas que encontrei na migração:

  • Depois de um tempo, o gemini-cli não realizava as etapas com eficiência.
  • Algumas vezes, mesmo com o passo a passo detalhado, o gemini-cli realizava ações diferenciadas. Por exemplo, algumas imagens com código foram ignoradas completamente.
  • Algumas vezes, o gemini-cli travava. Não sei a razão.
  • Algumas vezes, o gemini-cliachava que estava em looping e parava de realizar a tarefa. Isso é legal por um lado, pois tem uma detecção de looping, mas ruim por outro lado quando você sabe que a tarefa é demorada.

Algumas dicas que funcionaram bem:

  • Sempre passar um exemplo! Elimina um pouco da ambiguidade que surge em comunicação com linguagem natural.
  • A cada nova alteração de sucesso, criar um commit no git! Pois é muito mais fácil e garantido reverter em um cenário anterior com git do que pedir para o gemini-cli reverter as alterações.
  • Zerar o contexto. Contexto poluído ou que está em uso por um bom tempo, gera comportamentos inesperados nesta minha experiência.

Para migrar 31 artigos, levei +- 7h!

  • 1 hora para migrar dois artigos passo a passo. (Sem imagem com código)
  • 1 hora para migrar dois artigos passo a passo. (Imagem com código)
  • 1 hora para instruir a criação do código, limpeza e commit em um projeto novo.
  • 2 horas para o gemini-cli migrar 31 artigos. (Com erros e com alguns problemas de travamento)
  • 2 horas para revisar e arrumar os pequenos problemas. (Os 31 artigos e códigos que não foram extraídos de forma correta)

Ferramentas Utilizadas
#

Conclusão
#

Migrar 31 artigos do LinkedIn para o meu blog foi uma oportunidade incrível para aprender a automatizar tarefas complexas com a ajuda de uma ferramenta como o gemini-cli.

Ao criar um plano detalhado e delegar a execução, consegui transformar um trabalho que poderia levar dias em um processo gerenciável, muito mais rápido e principalmente divertido!

Agora, todos os meus artigos estão centralizados, em um formato que eu controlo e que é muito mais flexível para o futuro.

🥒🥒 Espero que tenham curtido e até o próximo artigo! 🥒🥒