"Qu'en est-il d'avoir été ingénieur pendant cinq ans et de ne produire aucune production?" J'ai ressenti un sentiment de crise, alors j'ai décidé de le poster sur Qiita. Il peut être difficile à lire car c'est le premier article, mais pardonnez-moi s'il vous plaît.
J'ai décidé d'utiliser Scrapbox pour les activités internes, mais j'ai finalement voulu mettre les pages dans Scrapbox sur un serveur de fichiers afin de pouvoir le laisser comme un actif interne. Scrapbox a une fonction pour exporter le contenu de toutes les pages sous forme de fichier JSON, mais il est difficile à lire tel quel. J'ai donc cherché un outil qui le convertirait en Markdown et l'enregistrerait, mais je n'ai pas trouvé d'outil qui avait l'air bien, alors je l'ai fait moi-même en utilisant Python.
Le fichier JSON exporté a ce format. (Exportation sans métadonnées.)
john-project.json
{
"name": "john-project",
"displayName": "john-project",
"exported": 1598595295,
"pages": [
{
"title": "Comment utiliser Scrapbox",
"created": 1598594744,
"updated": 1598594744,
"id": "000000000000000000000000",
"lines": [
"Comment utiliser Scrapbox",
"Bienvenue dans Scrapbox. Vous pouvez librement modifier et utiliser cette page.",
"",
"Invitez des membres à participer à ce projet",
//Omission
" [Nous publions des cas d'utilisation d'entreprises https://scrapbox.io/case]",
""
]
},
{
"title": "La première ligne est le titre",
"created": 1598594777,
"updated": 1598595231,
"id": "111111111111111111111111",
"lines": [
"La première ligne est le titre",
"[**Deux astérisques sont le style de titre]",
"Liste à puces avec retrait",
" \Si vous augmentez le nombre de t",
" [[Audacieux]]Ou[/ italic]、[-Ligne d'annulation]Peut être utilisé",
" \t comme ça[-/* italic]Peut être combiné",
"[Lien de page]Ou[Lien externe https://scrapbox.io]",
"code:test.py",
" for i in range(5):",
" print('[*Ignorer les blocs de code internes]')",
"",
"`[- code]`Ignorer",
"",
"table:Format tabulaire",
" aaa\tbbb\tccc",
"Ah ah\t\t Uuu",
"\t111\t222\t333",
""
]
}
]
}
À l'aide de l'outil que vous avez créé, il sera converti en un fichier Markdown comme celui ci-dessous. (* Afin d'améliorer l'apparence sur Qiita, il y a une partie où un espace pleine largeur est ajouté plus tard au bloc de code et à la fin de la ligne du tableau)
#La première ligne est le titre
###Deux astérisques sont le style de titre
-Liste à puces avec retrait
-Si vous augmentez le nombre, les caractères seront encore abaissés
- **Audacieux**Ou_italic_ 、 ~~Ligne d'annulation~~Peut être utilisé
-de cette façon_~~**italic**~~_Peut être combiné
[Lien de page]()Ou[Lienexterne](https://scrapbox.io)
code:test.py
```
for i in range(5):
print ('[* Ignorer les blocs de code internes]')
```
`[- code]`Ignorer
table:Format tabulaire
|aaa|bbb|ccc|
|-----|-----|-----|-----|
|Ah ah||Uuu|
|111|222|333|
L'apparence est convertie comme suit. Les sauts de ligne sont un peu lâches, mais c'est assez facile à voir.
De nombreux membres (y compris moi-même) sont nouveaux sur Scrapbox, et il semble qu'ils ne soient pas très élaborés, j'ai donc décidé de convertir uniquement les notations que je pourrais utiliser sans viser une conversion parfaite. La méthode de conversion est simple, utilisez simplement des expressions régulières pour trouver les parties écrites en notation Scrapbox et remplacez-les par le format Markdown. Enfin, exécutez-le pour qu'il puisse être utilisé par des personnes qui n'ont pas installé Python.
J'ai utilisé Windows10 et Python3.7.
Assurez-vous de recevoir le nom de fichier JSON comme premier argument. En faisant cela, vous pouvez l'utiliser en faisant simplement glisser et déposer le fichier JSON sur le fichier exe-ized. Créez également un dossier pour afficher Markdown.
filename = sys.argv[1]
with open(filename, 'r', encoding='utf-8') as fr:
sb = json.load(fr)
outdir = 'markdown/'
if not os.path.exists(outdir):
os.mkdir(outdir)
À partir de là, chaque page et chaque ligne seront converties dans l'ordre. Écrivez la cible de conversion entre () de chaque titre.
Scrapbox interprète la première ligne comme un titre, alors ajoutez `# '(espace net + demi-largeur) au début de la première ligne pour en faire un titre.
for p in sb['pages']:
title = p['title']
lines = p['lines']
is_in_codeblock = False
with open(f'{outdir}{title}.md', 'w', encoding='utf-8') as fw:
for i, l in enumerate(lines):
if i == 0:
l = '# ' + l
Dans Scrapbox, les blocs de code peuvent être représentés par code: hoge.ext
.
Tant que le début de la ligne est vide, le bloc de code continue.
Je ne veux pas convertir à l'intérieur du bloc de code, donc je vais continuer tout en déterminant si la ligne que je regarde est à l'intérieur du bloc de code.
Notation Markdown lors de l'entrée et de la sortie d'un bloc de code```
Ajouter.
# Traitement des blocs de code
if l.startswith('code:'):
is_in_codeblock = True
l += f'\n```'
elif is_in_codeblock and not l.startswith(('\t', ' ', ' ')):
is_in_codeblock = False
fw.write('```\n')
# Omission
# Convertir sinon un bloc de code
if not is_in_codeblock:
l = convert(l)
####table(`table:hoge`
)
Dans Scrapboxtable:hoge
Le tableau peut être exprimé avec.
Le tableau continue tant que la ligne commence par un espace.
Les tables Scrapbox n'ont pas d'en-têtes, mais Markdown ne peut pas représenter des tables sans en-têtes, donc il force la première ligne à être interprétée comme un en-tête.
Les cellules sont séparées par des tabulations, donc|
Convertir en.
Les blancs au début d'une ligne peuvent avoir des tabulations, des espaces demi-largeur et des espaces pleine largeur, de sorte qu'ils seront convertis en boueux.
if l.startswith('table:'):
is_in_table = True
elif is_in_table and not l.startswith(('\t', ' ', ' ')):
is_in_table = False
if is_in_table:
row += 1
if row != 0:
l = l.replace('\t', '|') + '|'
if l.startswith(' '):
l = l.replace(' ', '|', 1)
if row == 1:
col = l.count('|')
l += f'\n{"|-----" * col}|'
####code(`hoge`
)
Comme je ne veux pas convertir le code, j'ai mis un processus pour supprimer la partie de code avant le processus de conversion de chaque notation. Il est écrit de la même manière que Markdown, vous pouvez donc simplement le supprimer.
def ignore_code(l: str) -> str:
for m in re.finditer(r'`.+?`', l):
l = l.replace(m.group(0), '')
return l
####hashtag(#hoge
)
Si cela est écrit au début de la chaîne, il peut être interprété comme un titre par Markdown (cela semble différent selon le spectateur).
pour cette raison,`
Il est traité comme un code en l'enfermant dans.
def escape_hash_tag(l: str) -> str:
for m in re.finditer(r'#(.+?)[ \t]', ignore_code(l)):
l = l.replace(m.group(0), '`' + m.group(0) + '`')
if l.startswith ('#'): ligne # 1 pour toutes les balises
l = '`' + l + '`'
return l
####Liste à puces (retrait)
Le nombre de retraits est compté et remplacé par le format Markdown.
def convert_list(l: str) -> str:
m = re.match(r'[ \t ]+', l)
if m:
l = l.replace(m.group(0),
(len(m.group(0)) - 1) * ' ' + '- ', 1)
return l
####Audacieux ([[hoge]]
、[** hoge]
、[*** hoge]
)
Dans Scrapbox[[hoge]]
Ou[* hoge]
Si vous aimez, ce sera audacieux.
Aussi, dans cette dernière notation[** hoge]
Si vous augmentez l'astérisque comme dans, les caractères deviendront plus grands.
Parmi ces dernières notations, les notations avec deux et trois astérisques ont été utilisées comme des en-têtes Markdown, je les ai donc converties en conséquence. En dehors de cela, il peut être utilisé en même temps que d'autres décorations, il sera donc converti séparément.
def convert_bold(l: str) -> str:
for m in re.finditer(r'\[\[(.+?)\]\]', ignore_code(l)):
l = l.replace(m.group(0), '**' + m.group(1) + '**')
m = re.match (r '\ [(\ * \ * | \ * \ * \ *) (. +?) \]', Igno_code (l)) # Probablement l'en-tête
if m:
l = '#' * (5 - len(m.group(1))) + ' ' + \
m.group (2) #Scrapbox a plus *
return l
####Décoration de personnage ([* hoge]
、[/ hoge]
、[- hoge]
、[-/* hoge]
etc)
Dans Scrapbox, en plus de gras, diagonale[/ hoge]
Et ligne d'annulation[- hoge]
Peut être utilisé. Ceux-ci sont combinés[-/* hoge]
Puisqu'il peut être utilisé comme, il traite en même temps.
def convert_decoration(l: str) -> str:
for m in re.finditer(r'\[([-\*/]+) (.+?)\]', ignore_code(l)):
deco_s, deco_e = ' ', ' '
if '/' in m.group(0):
deco_s += '_'
deco_e = '_' + deco_e
if '-' in m.group(0):
deco_s += '~~'
deco_e = '~~' + deco_e
if '*' in m.group(0):
deco_s += '**'
deco_e = '**' + deco_e
l = l.replace(m.group(0), deco_s + m.group(2) + deco_e)
return l
(Le point culminant est étrange, mais je n'ai pas pu le réparer)
####Lien([Titre de l'URL]
、[URL du titre]
、[hoge]
)
Dans Scrapbox[Titre de l'URL]
Ou[URL du titre]
Exprimez le lien vers l'extérieur avec.
Ne pense pas à la chose exactehttp
J'ai décidé d'interpréter celui commençant par comme une URL.
Aussi,[hoge]
Un format comme celui-ci est un lien vers une autre page dans Scrapbox. Ce lien ne peut pas être utilisé après la sortie Markdown, mais derrière()
En ajoutant, seule l'apparence est comme un lien.
def convert_link(l: str) -> str:
for m in re.finditer(r'\[(.+?)\]', ignore_code(l)):
tmp = m.group(1).split(' ')
if len(tmp) == 2:
if tmp[0].startswith('http'):
link, title = tmp
else:
title, link = tmp
l = l.replace(m.group(0), f'[{title}]({link})')
else:
l = l.replace(m.group(0), m.group(0) + '()')
return l
###conversion exe
Enfin, utilisez pyinstaller pour exe. Créez un fichier exe sans affichage de la console.
pip install pyinstaller
pyinstaller sb2md.py -wF
Faites glisser le fichier JSON vers le fichier exe&Vous pouvez exécuter le programme en le supprimant.
##finalement
Le code créé cette fois estGitHubIl est placé dans. Lors de l'écriture d'un si petit processus, je trouve toujours Python utile.
J'ai commencé à utiliser Scrapbox l'autre jour, et je ne suis pas très doué pour le moment, donc je prévois de le mettre à jour dès qu'une autre utilisation sortira.
Recommended Posts