đŹđ§ Switch to English
Detta repository innehÄller Python-script för att konvertera SFS-författningar (Svensk författningssamling) frÄn JSON-format till Markdown med temporala taggar, HTML, Git och andra format.
Note
Detta Àr en del av SE-Lex, lÀs mer om projektet hÀr.
SFS-författningar exporteras till https://github.com/se-lex/sfs och publiceras ocksÄ som HTML pÄ https://selex.se med stöd för EU:s juridiska identifieringsstandard (ELI).
- Se till att du har Python 3.11 eller senare installerat
- Installera nödvÀndiga beroenden:
pip install -r requirements.txtKonvertera JSON-filer med författningar till Markdown:
python sfs_processor.py --input sfs_json --output output/md --formats md-markersVerktyget kan generera författningar i flera olika format, beroende pÄ anvÀndningsomrÄde:
md-markers(förvalt): Markdown med semantiska<section>-taggar och selex-attribut för juridisk status och temporal hanteringmd: Rena Markdown-filer med normaliserade rubriknivÄer, lÀmpliga för visning och lÀsning. UtgÄr frÄn ett target-date (förvalt: dagens datum) för att visa hur lagen ser ut vid den tidpunkten
git: Exporterar författningar som Git-commits med historiska datum, vilket skapar en versionshistorik av lagstiftningen
html: Genererar HTML-filer i ELI-struktur (/eli/sfs/{Är}/{nummer}/index.html) för webbpubliceringhtmldiff: Som HTML men inkluderar Àven separata versioner för varje Àndringsförfattning
HTML-filer kan publiceras via:
- Cloudflare R2: Med
html-export-workflow.yml(krÀver R2-credentials) - GitHub Pages: Med
github-pages-workflow.yml(enklare setup, krÀver aktiverad GitHub Pages)
vector: Konverterar författningar till vektorembeddings för semantisk sökning och RAG-applikationer. AnvÀnder OpenAI:s text-embedding-3-large modell (3072 dimensioner) och stödjer lagring i PostgreSQL (pgvector), Elasticsearch eller JSON-fil.
Exempel pÄ att kombinera flera format:
python sfs_processor.py --input sfs_json --output output --formats md,html,gitFör att konvertera författningar behöver du först ladda ner JSON-data:
python downloaders/download_sfs_docs.py --ids all --source rkrattsbaserpython downloaders/download_sfs_docs.py --ids "2024:675,2024:700" --source rkrattsbaserNedladdade filer sparas som standard i katalogen sfs_docs. Du kan ange annan katalog med --out parametern.
Konvertera alla JSON-filer i en katalog till Markdown:
python sfs_processor.py --input sfs_json --output output/md --formats md-markersBeroende pÄ vilket format du vÀljer fÄr du olika strukturer:
Markdown-filer med bevarad semantisk struktur genom <article> och <section>-taggar:
<article>: Omsluter hela författningen och kan innehÄlla temporala attribut (ikraft_datum, upphor_datum, etc.)<section class="avdelning">: Omsluter avdelningar (divisions) som överordnad strukturell enhet<section class="kapitel">: Omsluter kapitel som strukturell enhet med underliggande paragrafer<section class="paragraf">: Omsluter varje paragraf (§) som en avgrÀnsad juridisk bestÀmmelse
<article selex:status="ikraft" selex:ikraft_datum="2025-01-01">
# Lag (2024:123) om exempel
<section class="avdelning" id="avd1">
## AVDELNING I. ALLMĂNNA BESTĂMMELSER
<section class="kapitel" id="inledande-bestammelser">
### Inledande bestÀmmelser
<section class="paragraf" id="inledande-bestammelser.1">
#### 1 §
InnehÄllet i paragrafen...
</section>
</section>
</section>
</article>Denna semantiska struktur bevarar dokumentets logiska uppbyggnad och möjliggör automatisk bearbetning, analys, och navigation av författningstexten. ID-attributen gör det möjligt att lÀnka direkt till specifika rubriker och paragrafer (t.ex. #inledande-bestammelser.1). Taggarna kan Àven anvÀndas för CSS-styling och JavaScript-funktionalitet.
OBS! Trots HTML-taggarna Àr filerna fortfarande fullt lÀsbara som Markdown :)
Rena Markdown-filer med normaliserade rubriknivÄer, utan section-taggar:
# Lag (2024:123) om exempel
## Inledande bestÀmmelser
### 1 §
InnehÄllet i paragrafen...
### 2 §
Mer innehÄll...Detta format Àr lÀmpligt för enkel visning och lÀsning, utan metadata eller temporal hantering.
Förutom CSS-klasser anvÀnder <section>-taggarna Àven selex:-attribut för att hantera juridisk status och datum. Dessa attribut möjliggör filtrering av innehÄll baserat pÄ ikrafttrÀdande- och upphörandedatum:
-
selex:status: Anger sektionens juridiska statusikraft: Sektionen innehÄller ikrafttrÀdanderegler (konverterat frÄn t.ex. "/TrÀder i kraft I:2025-01-01")upphavd: Sektionen Àr upphÀvd (konverterad frÄn ifall rubrik innehÄller "upphÀvd" eller "/Upphör att gÀlla")
-
selex:ikraft_datum: Datum dÄ sektionen trÀder ikraft (format: YYYY-MM-DD) -
selex:upphor_datum: Datum dÄ sektionen upphör att gÀlla (format: YYYY-MM-DD) -
selex:ikraft_villkor: Villkor för ikrafttrÀdande (nÀr inget specifikt datum anges)
Exempel pÄ selex-attribut:
<section class="kapitel" selex:status="ikraft" selex:ikraft_datum="2025-01-01">
### 1 § En paragraf
...
</section>
<section class="paragraf" selex:status="upphavd" selex:upphor_datum="2023-12-31">
#### 2 § En paragraf
...
</section>
<section class="kapitel" selex:status="ikraft" selex:ikraft_villkor="den dag regeringen bestÀmmer">
### 3 § Rubrik pÄ villkorad ikrafttrÀdande
...
</section>Dessa attribut anvÀnds automatiskt av systemets datumfiltrering för att skapa versioner av författningar som gÀller vid specifika tidpunkter. Sektioner med selex:upphor_datum som har passerat tas bort, och sektioner med selex:ikraft_datum som Ànnu inte har kommit tas bort frÄn den aktuella versionen.
Systemet hanterar temporal processing (tidsbaserad filtrering) olika beroende pÄ vilket format som anvÀnds:
-
md-markers(förvalt): Bevarar selex-taggar och hoppar över temporal processing. Detta gör att alla temporal attribut behÄlls för senare bearbetning. Rekommenderas för att bevara all juridisk metadata. -
md: TillÀmpar temporal processing med dagens datum som mÄlpunkt. Detta Àr viktigt att förstÄ:- UpphÀvda bestÀmmelser (med
selex:upphor_datumföre dagens datum) tas bort - BestÀmmelser som Ànnu inte trÀtt i kraft (med
selex:ikraft_datumefter dagens datum) tas bort - Selex-taggar tas bort efter filtrering
- Resultatet blir en "ren" Markdown-vy av hur lagen ser ut idag
- Obs: Eftersom temporal filtrering anvÀnds automatiskt, kan innehÄll försvinna om det Àr upphÀvt eller ej ikrafttrÀtt
- UpphÀvda bestÀmmelser (med
-
git: Hoppar över temporal processing i huvudbearbetningen. Temporal hantering sköts separat i git-arbetsflödet för att skapa historiska commits. -
htmlochhtmldiff: TillÀmpar temporal processing med dagens datum innan HTML-generering, liknandemd-format. -
vector: TillÀmpar temporal processing med dagens datum (eller angivet--target-date) innan vektorgenerering. Detta sÀkerstÀller att endast gÀllande regelverk inkluderas i vektordatabasen.
För att se hur en lag sÄg ut vid ett specifikt datum:
# Se hur lagen sÄg ut 2023-01-01
python sfs_processor.py --input sfs_json --output output/md --formats md --target-date 2023-01-01Detta Àr anvÀndbart för att skapa historiska versioner eller för att förstÄ hur lagen sÄg ut vid en viss tidpunkt.
python sfs_processor.py [--input INPUT] [--output OUTPUT] [--formats FORMATS] [--filter FILTER] [--target-date DATE] [--no-year-folder] [--verbose]--input: Input-katalog med JSON-filer (default: "sfs_json")--output: Output-katalog för konverterade filer (default: "SFS")--formats: Utdataformat att generera, kommaseparerat. Stödjer: md-markers, md, git, html, htmldiff, vector (default: "md-markers")md-markers: Generera markdown-filer med section-taggar bevarademd: Generera rena markdown-filer utan section-taggargit: Aktivera Git-commits med historiska datumhtml: Generera HTML-filer i ELI-struktur (endast grunddokument)htmldiff: Generera HTML-filer i ELI-struktur med Àndringsversionervector: Generera vektorembeddings för semantisk sökning
--filter: Filtrera filer efter Är (YYYY) eller specifik beteckning (YYYY:NNN). Kan vara kommaseparerad lista.--target-date: Datum (YYYY-MM-DD) för temporal filtrering, baserat pÄ selex-taggar. AnvÀnds medmd,html,htmldiffochvectorformat för att filtrera innehÄll baserat pÄ giltighetsdatum. Om inte angivet anvÀnds dagens datum. Exempel:--target-date 2023-01-01--no-year-folder: Skapa inte Ärbaserade undermappar för dokument--verbose: Visa detaljerad information om bearbetningen
--vector-backend: Backend för vektorlagring (default: "json")json: Spara till JSON-fil (för test/utveckling)postgresql: PostgreSQL med pgvector-extensionelasticsearch: Elasticsearch med dense_vector
--vector-chunking: Strategi för att dela upp dokument (default: "paragraph")paragraph: Dela per paragraf (§) - bevarar juridisk strukturchapter: Dela per kapitel - större kontextsection: Dela per selex-sektionsemantic: Semantiska grÀnser med överlappfixed_size: Fast tokenantal med överlapp
--embedding-model: Embedding-modell (default: "text-embedding-3-large")--vector-mock: AnvÀnd mock-embeddings för test utan OpenAI API-nyckel
Vektorformatet (--formats vector) konverterar författningar till vektorembeddings som kan anvÀndas för semantisk sökning, RAG-applikationer (Retrieval-Augmented Generation) och AI-assistenter.
- Temporal filtrering: Endast gÀllande regelverk inkluderas (samma som
md/htmlmode) - Intelligent chunking: Dokument delas upp pÄ ett sÀtt som bevarar juridisk struktur
- Embedding-generering: Text konverteras till vektorer med OpenAI text-embedding-3-large
- Lagring: Vektorer sparas till vald backend med fullstÀndig metadata
# Test med mock-embeddings (utan API-nyckel)
python sfs_processor.py --formats vector --vector-mock --filter 2024:100
# Produktion med OpenAI (krÀver OPENAI_API_KEY miljövariabel)
python sfs_processor.py --formats vector --filter 2024
# Med PostgreSQL/pgvector backend
python sfs_processor.py --formats vector --vector-backend postgresql
# Med kapitel-chunking för större kontext
python sfs_processor.py --formats vector --vector-chunking chapter| Backend | AnvÀndning | Krav |
|---|---|---|
json |
Test/utveckling | Inga |
postgresql |
Produktion | PostgreSQL 12+ med pgvector |
elasticsearch |
Produktion | Elasticsearch 8.0+ |
Varje vektor-chunk innehÄller:
document_id: Beteckning (t.ex. "2024:100")chapter: Kapitelreferens (t.ex. "1 kap.")paragraph: Paragrafreferens (t.ex. "1 §")departement: Ansvarigt departementeffective_date: IkrafttrÀdande-datum
Vi vĂ€lkomnar bidrag frĂ„n communityn! đ
- LÀs CONTRIBUTING.md för riktlinjer om hur du bidrar
- Se DEVELOPMENT.md för utvecklardokumentation och arkitekturöversikt
- Kontakt: Martin Rimskog via e-post eller LinkedIn