om4r932 commited on
Commit
9c5671b
·
1 Parent(s): d6c5e41

Add website

Browse files
Files changed (4) hide show
  1. README.md +1 -1
  2. index.html +24 -19
  3. script.js +159 -0
  4. style.css +142 -17
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 👁
4
  colorFrom: purple
5
  colorTo: pink
6
  sdk: static
7
- pinned: false
8
  license: gpl-3.0
9
  short_description: A static website that displays 3GPP specifications via JSON
10
  ---
 
4
  colorFrom: purple
5
  colorTo: pink
6
  sdk: static
7
+ pinned: true
8
  license: gpl-3.0
9
  short_description: A static website that displays 3GPP specifications via JSON
10
  ---
index.html CHANGED
@@ -1,19 +1,24 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>3GPP Specification Visualizor</title>
8
+ <link rel="stylesheet" href="style.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="header">
13
+ <h1>Visualiseur de Spécifications 3GPP</h1>
14
+ <div class="file-input-container"> <input type="file" id="fileInput" accept=".json">
15
+ <div id="fileInfo"></div>
16
+ </div>
17
+ </div>
18
+ <div id="document-container">
19
+ <div class="loading">Veuillez charger un fichier de spécification 3GPP</div>
20
+ </div>
21
+ <script src="script.js"></script>
22
+ </body>
23
+
24
+ </html>
script.js ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.getElementById('fileInput').addEventListener('change', handleFileSelect);
2
+
3
+ function handleFileSelect(event) {
4
+ const file = event.target.files[0];
5
+ if (!file) return;
6
+
7
+ const fileNameMatch = file.name.match(/(\d+\.\d+(?:-\d+)?)[_-]([a-z0-9]+)\.json/i);
8
+ let fileInfoText = '';
9
+
10
+ if (fileNameMatch) {
11
+ const specNumber = fileNameMatch[1];
12
+ const versionCode = fileNameMatch[2];
13
+
14
+ // Conversion des caractères en numéro de version
15
+ let versionString = "";
16
+ for (let i = 0; i < versionCode.length; i++) {
17
+ let char = versionCode[i].toLowerCase();
18
+ let versionPart;
19
+
20
+ if (/[0-9]/.test(char)) {
21
+ versionPart = parseInt(char, 10);
22
+ } else if (/[a-z]/.test(char)) {
23
+ versionPart = char.charCodeAt(0) - 'a'.charCodeAt(0) + 10;
24
+ } else {
25
+ versionPart = "?";
26
+ }
27
+
28
+ if (i > 0) versionString += ".";
29
+ versionString += versionPart;
30
+ }
31
+
32
+ fileInfoText = `Spécification ${specNumber}, Version ${versionString}`;
33
+ document.getElementById('fileInfo').textContent = fileInfoText;
34
+ } else {
35
+ document.getElementById('fileInfo').textContent = file.name;
36
+ }
37
+
38
+ const reader = new FileReader();
39
+ reader.onload = function (e) {
40
+ try {
41
+ const jsonContent = JSON.parse(e.target.result);
42
+ renderDocument(jsonContent);
43
+ } catch (error) {
44
+ document.getElementById('document-container').innerHTML =
45
+ `<div class="error">Erreur lors du traitement du fichier JSON: ${error.message}</div>`;
46
+ }
47
+ };
48
+ reader.readAsText(file);
49
+ }
50
+
51
+ function renderDocument(jsonContent) {
52
+ const container = document.getElementById('document-container');
53
+ container.innerHTML = '';
54
+
55
+ // Parcourir tous les éléments du JSON
56
+ Object.entries(jsonContent).forEach(([key, value]) => {
57
+ // Déterminer le niveau de titre basé sur la clé
58
+ if (key.match(/^\d+$/)) {
59
+ // Section principale (ex: "1 Scope")
60
+ const section = document.createElement('div');
61
+ section.className = 'section';
62
+
63
+ const title = document.createElement('h2');
64
+ title.textContent = key;
65
+ section.appendChild(title);
66
+
67
+ const content = document.createElement('div');
68
+ content.innerHTML = formatText(value);
69
+ section.appendChild(content);
70
+
71
+ container.appendChild(section);
72
+ } else if (key.match(/^\d+\.\d+$/)) {
73
+ // Sous-section (ex: "3.1 Definitions")
74
+ const subsection = document.createElement('div');
75
+ subsection.className = 'subsection';
76
+
77
+ const title = document.createElement('h3');
78
+ title.textContent = key;
79
+ subsection.appendChild(title);
80
+
81
+ const content = document.createElement('div');
82
+ content.innerHTML = formatText(value);
83
+ subsection.appendChild(content);
84
+
85
+ container.appendChild(subsection);
86
+ } else {
87
+ // Autres éléments
88
+ const div = document.createElement('div');
89
+ const title = document.createElement('h3');
90
+ title.textContent = key;
91
+ div.appendChild(title);
92
+
93
+ const content = document.createElement('div');
94
+ content.innerHTML = formatText(value);
95
+ div.appendChild(content);
96
+
97
+ container.appendChild(div);
98
+ }
99
+ });
100
+ }
101
+
102
+ function formatText(text) {
103
+ if (!text) return '';
104
+
105
+ // Remplacer les sauts de ligne
106
+ let formattedText = text.replace(/\n/g, '<br>');
107
+
108
+ // Formatage des tableaux (détection basique de structures tabulaires)
109
+ if (text.includes('Byte') && (text.includes('b8') || text.includes('b7'))) {
110
+ // Tenter de détecter et convertir les représentations de tables de bits
111
+ formattedText = formatBitTables(formattedText);
112
+ }
113
+
114
+ // Mise en évidence des termes techniques
115
+ formattedText = formattedText.replace(/\b([A-Z]{2,}(?:-[A-Z]+)*)\b/g, '<span class="code-block">$1</span>');
116
+
117
+ return formattedText;
118
+ }
119
+
120
+ function formatBitTables(text) {
121
+ // Exemple simple pour détecter et formater les tableaux de bits
122
+ // Une implémentation plus robuste nécessiterait une analyse plus complexe
123
+
124
+ // Détection basique d'un en-tête de table de bits
125
+ const tableHeaders = text.match(/b8\s+b7\s+b6\s+b5\s+b4\s+b3\s+b2\s+b1/g);
126
+
127
+ if (tableHeaders) {
128
+ // Remplacer les occurrences par une table HTML
129
+ tableHeaders.forEach(header => {
130
+ const tableStart =
131
+ '<table class="byte-table"><tr><th>b8</th><th>b7</th><th>b6</th><th>b5</th><th>b4</th><th>b3</th><th>b2</th><th>b1</th></tr>';
132
+ const tableEnd = '</table>';
133
+
134
+ // Essayer de capturer les lignes suivantes qui pourraient être des données de table
135
+ const headerPos = text.indexOf(header);
136
+ const nextLineStart = text.indexOf('<br>', headerPos) + 4;
137
+ let tableContent = '';
138
+
139
+ // Ajouter des lignes jusqu'à ce qu'on atteigne une ligne vide ou un nouveau paragraphe
140
+ let currentPos = nextLineStart;
141
+ let endPos = text.indexOf('<br><br>', currentPos);
142
+ if (endPos === -1) endPos = text.length;
143
+
144
+ const potentialTableData = text.substring(currentPos, endPos);
145
+ const rows = potentialTableData.split('<br>');
146
+
147
+ rows.forEach(row => {
148
+ if (row.trim() && !row.includes('Byte') && !row.includes('b8')) {
149
+ tableContent += '<tr><td colspan="8">' + row + '</td></tr>';
150
+ }
151
+ });
152
+
153
+ const tableHTML = tableStart + tableContent + tableEnd;
154
+ text = text.replace(header + potentialTableData, tableHTML);
155
+ });
156
+ }
157
+
158
+ return text;
159
+ }
style.css CHANGED
@@ -1,28 +1,153 @@
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
  h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  body {
2
+ font-family: Arial, sans-serif;
3
+ line-height: 1.6;
4
+ max-width: 1100px;
5
+ margin: 0 auto;
6
+ padding: 20px;
7
+ color: #333;
8
+ }
9
+
10
+ .header {
11
+ margin-bottom: 30px;
12
+ padding-bottom: 15px;
13
+ border-bottom: 1px solid #ddd;
14
+ }
15
+
16
+ .file-input-container {
17
+ margin-bottom: 20px;
18
+ }
19
+
20
+ #fileInfo {
21
+ margin-top: 10px;
22
+ font-style: italic;
23
+ color: #666;
24
  }
25
 
26
  h1 {
27
+ color: #2c5282;
28
+ }
29
+
30
+ h2 {
31
+ color: #2a4365;
32
+ margin-top: 40px;
33
+ padding-bottom: 8px;
34
+ border-bottom: 1px solid #eaeaea;
35
+ }
36
+
37
+ h3 {
38
+ color: #2c5282;
39
+ margin-top: 25px;
40
  }
41
 
42
+ #document-container {
43
+ background-color: white;
44
+ padding: 20px;
45
+ border: 1px solid #ddd;
46
+ border-radius: 5px;
47
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
48
  }
49
 
50
+ .section {
51
+ margin-bottom: 20px;
 
 
 
 
52
  }
53
 
54
+ .subsection {
55
+ margin-left: 15px;
56
  }
57
+
58
+ table {
59
+ width: 100%;
60
+ border-collapse: collapse;
61
+ margin: 15px 0;
62
+ }
63
+
64
+ table,
65
+ th,
66
+ td {
67
+ border: 1px solid #ddd;
68
+ }
69
+
70
+ th,
71
+ td {
72
+ padding: 12px;
73
+ text-align: left;
74
+ }
75
+
76
+ th {
77
+ background-color: #f2f2f2;
78
+ }
79
+
80
+ pre {
81
+ background-color: #f8f8f8;
82
+ padding: 10px;
83
+ border-radius: 5px;
84
+ overflow-x: auto;
85
+ font-family: Consolas, monospace;
86
+ }
87
+
88
+ .loading {
89
+ text-align: center;
90
+ padding: 40px;
91
+ font-size: 20px;
92
+ color: #666;
93
+ }
94
+
95
+ .error {
96
+ color: #e53e3e;
97
+ padding: 10px;
98
+ background-color: #fff5f5;
99
+ border-left: 4px solid #e53e3e;
100
+ margin: 15px 0;
101
+ }
102
+
103
+ #fileInput {
104
+ padding: 10px;
105
+ border: 1px solid #ddd;
106
+ border-radius: 4px;
107
+ width: 100%;
108
+ max-width: 400px;
109
+ }
110
+
111
+ button {
112
+ background-color: #3182ce;
113
+ color: white;
114
+ border: none;
115
+ padding: 10px 15px;
116
+ border-radius: 4px;
117
+ cursor: pointer;
118
+ transition: background-color 0.3s;
119
+ }
120
+
121
+ button:hover {
122
+ background-color: #2c5282;
123
+ }
124
+
125
+ @media print {
126
+ .file-input-container {
127
+ display: none;
128
+ }
129
+
130
+ body {
131
+ padding: 0;
132
+ max-width: none;
133
+ }
134
+
135
+ #document-container {
136
+ border: none;
137
+ box-shadow: none;
138
+ padding: 0;
139
+ }
140
+ }
141
+
142
+ /* Styles pour meilleure lisibilité des tableaux et contenus techniques */
143
+ .byte-table td {
144
+ font-family: Consolas, monospace;
145
+ font-size: 14px;
146
+ }
147
+
148
+ .code-block {
149
+ font-family: Consolas, monospace;
150
+ background-color: #f8f8f8;
151
+ padding: 2px 4px;
152
+ border-radius: 3px;
153
+ }