Add humans.txt tool
This commit is contained in:
parent
1c7f0e2ee3
commit
c8c0cef554
@ -30,6 +30,7 @@ export default {
|
|||||||
'explain_crontab': 'Explain crontab',
|
'explain_crontab': 'Explain crontab',
|
||||||
'table_to_mediawiki_table': 'Table to Mediawiki table',
|
'table_to_mediawiki_table': 'Table to Mediawiki table',
|
||||||
'dummy_image': 'Dummy image',
|
'dummy_image': 'Dummy image',
|
||||||
|
'humans_txt': 'humans.txt generator',
|
||||||
},
|
},
|
||||||
'Strings': {
|
'Strings': {
|
||||||
'fix_ru_en_keyboard': 'Fix ru-en keyboard',
|
'fix_ru_en_keyboard': 'Fix ru-en keyboard',
|
||||||
|
@ -26,6 +26,11 @@ const router = createRouter({
|
|||||||
name: 'dummy_image',
|
name: 'dummy_image',
|
||||||
component: () => import('../views/DummyImage.vue'),
|
component: () => import('../views/DummyImage.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/humans_txt',
|
||||||
|
name: 'humans_txt',
|
||||||
|
component: () => import('../views/HumansTxt.vue'),
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String manipulation
|
* String manipulation
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="result">Result</label>
|
<label for="result">Result</label>
|
||||||
<div :style="{'width': toolData.width, 'height': toolData.height}">
|
<div :style="{'width': toolData.width, 'height': toolData.height}">
|
||||||
<canvas ref="canvas" :width="toolData.width" :height="toolData.height"></canvas>
|
<canvas ref="canvas" :width="toolData.width" :height="toolData.height" style="max-width: 50vw; max-height: 50vh;"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
370
src/views/HumansTxt.vue
Normal file
370
src/views/HumansTxt.vue
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
<template>
|
||||||
|
<h2 class="tool-title">humans.txt generator</h2>
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Team <button @click="addTeamGroup">+</button></label>
|
||||||
|
<div class="humans-group" v-for="(group, groupIndex) in toolData.team" :key="groupIndex">
|
||||||
|
<div v-for="(field, fieldIndex) in group" :key="fieldIndex">
|
||||||
|
<input class="input" v-model="field.key" v-on:keyup="result" placeholder="Key" type="text">
|
||||||
|
<input class="input" v-model="field.value" v-on:keyup="result" placeholder="Value" type="text">
|
||||||
|
<button @click="removeTeamField(groupIndex, fieldIndex)">🞩</button>
|
||||||
|
<button @click="moveTeamFieldUp(groupIndex, fieldIndex)" v-show="fieldIndex !== 0">↑</button>
|
||||||
|
<button @click="moveTeamFieldDown(groupIndex, fieldIndex)" v-show="fieldIndex !== group.length - 1">↓</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button @click="addTeamField(groupIndex)">+</button>
|
||||||
|
<button @click="removeTeamGroup(groupIndex)">🞩</button>
|
||||||
|
<button @click="moveTeamGroupUp(groupIndex)" v-show="groupIndex !== 0">↑</button>
|
||||||
|
<button @click="moveTeamGroupDown(groupIndex)" v-show="groupIndex !== toolData.team.length - 1">↓</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Thanks <button @click="addThanksGroup">+</button></label>
|
||||||
|
<div class="humans-group" v-for="(group, groupIndex) in toolData.thanks" :key="groupIndex">
|
||||||
|
<div v-for="(field, fieldIndex) in group" :key="fieldIndex">
|
||||||
|
<input class="input" v-model="field.key" v-on:keyup="result" placeholder="Key" type="text">
|
||||||
|
<input class="input" v-model="field.value" v-on:keyup="result" placeholder="Value" type="text">
|
||||||
|
<button @click="removeThanksField(groupIndex, fieldIndex)">🞩</button>
|
||||||
|
<button @click="moveThanksFieldUp(groupIndex, fieldIndex)" v-show="fieldIndex !== 0">↑</button>
|
||||||
|
<button @click="moveThanksFieldDown(groupIndex, fieldIndex)" v-show="fieldIndex !== group.length - 1">↓</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button @click="addThanksField(groupIndex)">+</button>
|
||||||
|
<button @click="removeThanksGroup(groupIndex)">🞩</button>
|
||||||
|
<button @click="moveThanksGroupUp(groupIndex)" v-show="groupIndex !== 0">↑</button>
|
||||||
|
<button @click="moveThanksGroupDown(groupIndex)" v-show="groupIndex !== toolData.thanks.length - 1">↓</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Site info <button @click="addSite">+</button></label>
|
||||||
|
<div v-for="(info, fieldIndex) in toolData.site" :key="fieldIndex">
|
||||||
|
<input class="input" v-model="info.key" v-on:keyup="result" placeholder="Key" type="text">
|
||||||
|
<input class="input" v-model="info.value" v-on:keyup="result" placeholder="Value" type="text">
|
||||||
|
<button @click="removeSiteField(fieldIndex)">🞩</button>
|
||||||
|
<button @click="moveSiteUp(fieldIndex)" v-show="fieldIndex !== 0">↑</button>
|
||||||
|
<button @click="moveSiteDown(fieldIndex)" v-show="fieldIndex !== toolData.site.length - 1">↓</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Import humans.txt <button @click="importHumans">Import</button></label>
|
||||||
|
<textarea v-model="toolData.importedHumansTxt" style="height: 250px"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="result">Result</label>
|
||||||
|
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MonacoEditor from "@/components/MonacoEditor.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
MonacoEditor
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
toolData: {
|
||||||
|
team: [
|
||||||
|
[
|
||||||
|
{ key: '', value: '' }
|
||||||
|
]
|
||||||
|
],
|
||||||
|
thanks: [
|
||||||
|
[
|
||||||
|
{ key: '', value: '' }
|
||||||
|
]
|
||||||
|
],
|
||||||
|
site: [
|
||||||
|
{ key: '', value: '' }
|
||||||
|
],
|
||||||
|
importedHumansTxt: ''
|
||||||
|
},
|
||||||
|
toolResult: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.importHumans();
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* Team
|
||||||
|
*/
|
||||||
|
addTeamGroup() {
|
||||||
|
this.toolData.team.push([{ key: '', value: '' }]);
|
||||||
|
},
|
||||||
|
addTeamField(groupIndex) {
|
||||||
|
this.toolData.team[groupIndex].push({ key: '', value: '' });
|
||||||
|
},
|
||||||
|
removeTeamField(groupIndex, fieldIndex) {
|
||||||
|
this.toolData.team[groupIndex].splice(fieldIndex, 1);
|
||||||
|
|
||||||
|
if (this.toolData.team[groupIndex].length == 0) {
|
||||||
|
this.removeTeamGroup(groupIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
removeTeamGroup(groupIndex) {
|
||||||
|
this.toolData.team.splice(groupIndex, 1);
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveTeamGroupUp(groupIndex) {
|
||||||
|
if (groupIndex > 0) {
|
||||||
|
const temp = this.toolData.team[groupIndex];
|
||||||
|
this.toolData.team[groupIndex] = this.toolData.team[groupIndex - 1];
|
||||||
|
this.toolData.team[groupIndex - 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveTeamGroupDown(groupIndex) {
|
||||||
|
if (groupIndex < this.toolData.team.length - 1) {
|
||||||
|
const temp = this.toolData.team[groupIndex];
|
||||||
|
this.toolData.team[groupIndex] = this.toolData.team[groupIndex + 1];
|
||||||
|
this.toolData.team[groupIndex + 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveTeamFieldUp(groupIndex, fieldIndex) {
|
||||||
|
if (fieldIndex > 0) {
|
||||||
|
const temp = this.toolData.team[groupIndex][fieldIndex];
|
||||||
|
this.toolData.team[groupIndex][fieldIndex] = this.toolData.team[groupIndex][fieldIndex - 1];
|
||||||
|
this.toolData.team[groupIndex][fieldIndex - 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveTeamFieldDown(groupIndex, fieldIndex) {
|
||||||
|
if (fieldIndex < this.toolData.team[groupIndex].length - 1) {
|
||||||
|
const temp = this.toolData.team[groupIndex][fieldIndex];
|
||||||
|
this.toolData.team[groupIndex][fieldIndex] = this.toolData.team[groupIndex][fieldIndex + 1];
|
||||||
|
this.toolData.team[groupIndex][fieldIndex + 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thank
|
||||||
|
*/
|
||||||
|
addThanksGroup() {
|
||||||
|
this.toolData.thanks.push([{ key: '', value: '' }]);
|
||||||
|
},
|
||||||
|
addThanksField(groupIndex) {
|
||||||
|
this.toolData.thanks[groupIndex].push({ key: '', value: '' });
|
||||||
|
},
|
||||||
|
removeThanksField(groupIndex, fieldIndex) {
|
||||||
|
this.toolData.thanks[groupIndex].splice(fieldIndex, 1);
|
||||||
|
|
||||||
|
if (this.toolData.thanks[groupIndex].length == 0) {
|
||||||
|
this.removeThanksGroup(groupIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
removeThanksGroup(groupIndex) {
|
||||||
|
this.toolData.thanks.splice(groupIndex, 1);
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveThanksGroupUp(groupIndex) {
|
||||||
|
if (groupIndex > 0) {
|
||||||
|
const temp = this.toolData.thanks[groupIndex];
|
||||||
|
this.toolData.thanks[groupIndex] = this.toolData.thanks[groupIndex - 1];
|
||||||
|
this.toolData.thanks[groupIndex - 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveThanksGroupDown(groupIndex) {
|
||||||
|
if (groupIndex < this.toolData.thanks.length - 1) {
|
||||||
|
const temp = this.toolData.thanks[groupIndex];
|
||||||
|
this.toolData.thanks[groupIndex] = this.toolData.thanks[groupIndex + 1];
|
||||||
|
this.toolData.thanks[groupIndex + 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveThanksFieldUp(groupIndex, fieldIndex) {
|
||||||
|
if (fieldIndex > 0) {
|
||||||
|
const temp = this.toolData.thanks[groupIndex][fieldIndex];
|
||||||
|
this.toolData.thanks[groupIndex][fieldIndex] = this.toolData.thanks[groupIndex][fieldIndex - 1];
|
||||||
|
this.toolData.thanks[groupIndex][fieldIndex - 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveThanksFieldDown(groupIndex, fieldIndex) {
|
||||||
|
if (fieldIndex < this.toolData.thanks[groupIndex].length - 1) {
|
||||||
|
const temp = this.toolData.thanks[groupIndex][fieldIndex];
|
||||||
|
this.toolData.thanks[groupIndex][fieldIndex] = this.toolData.thanks[groupIndex][fieldIndex + 1];
|
||||||
|
this.toolData.thanks[groupIndex][fieldIndex + 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Site
|
||||||
|
*/
|
||||||
|
addSite() {
|
||||||
|
this.toolData.site.push({ label: '', value: '' });
|
||||||
|
},
|
||||||
|
removeSiteField(fieldIndex) {
|
||||||
|
this.toolData.site.splice(fieldIndex, 1);
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveSiteUp(index) {
|
||||||
|
if (index > 0) {
|
||||||
|
const temp = this.toolData.site[index];
|
||||||
|
this.toolData.site[index] = this.toolData.site[index - 1];
|
||||||
|
this.toolData.site[index - 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
moveSiteDown(index) {
|
||||||
|
if (index < this.toolData.site.length - 1) {
|
||||||
|
const temp = this.toolData.site[index];
|
||||||
|
this.toolData.site[index] = this.toolData.site[index + 1];
|
||||||
|
this.toolData.site[index + 1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.result();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import
|
||||||
|
*/
|
||||||
|
importHumans() {
|
||||||
|
const lines = this.toolData.importedHumansTxt.split('\n');
|
||||||
|
let currentSection = null;
|
||||||
|
|
||||||
|
this.toolData.team = [];
|
||||||
|
this.toolData.thanks = [];
|
||||||
|
this.toolData.site = [];
|
||||||
|
|
||||||
|
let currentGroup = [];
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.toLowerCase().startsWith('/* TEAM */'.toLowerCase())) {
|
||||||
|
currentSection = 'team';
|
||||||
|
} else if (line.toLowerCase().startsWith('/* THANKS */'.toLowerCase())) {
|
||||||
|
currentSection = 'thanks';
|
||||||
|
} else if (line.toLowerCase().startsWith('/* SITE */'.toLowerCase())) {
|
||||||
|
currentSection = 'site';
|
||||||
|
} else if (line.trim() !== '') {
|
||||||
|
if (currentSection === 'team') {
|
||||||
|
const [key, value] = line.split(':');
|
||||||
|
currentGroup.push({ key: key.trim(), value: value.trim() });
|
||||||
|
} else if (currentSection === 'thanks') {
|
||||||
|
const [key, value] = line.split(':');
|
||||||
|
currentGroup.push({ key: key.trim(), value: value.trim() });
|
||||||
|
} else if (currentSection === 'site') {
|
||||||
|
const [key, value] = line.split(':');
|
||||||
|
this.toolData.site.push({ key: key.trim(), value: value.trim() });
|
||||||
|
}
|
||||||
|
} else if (line.trim() === '' && currentSection === 'team') {
|
||||||
|
if (currentGroup.length > 0) {
|
||||||
|
this.toolData.team.push(currentGroup);
|
||||||
|
currentGroup = [];
|
||||||
|
}
|
||||||
|
} else if (line.trim() === '' && currentSection === 'thanks') {
|
||||||
|
if (currentGroup.length > 0) {
|
||||||
|
this.toolData.thanks.push(currentGroup);
|
||||||
|
currentGroup = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentGroup.length > 0) {
|
||||||
|
this.toolData.team.push(currentGroup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate
|
||||||
|
*/
|
||||||
|
result() {
|
||||||
|
let output = '';
|
||||||
|
|
||||||
|
if (this.toolData.team.length) {
|
||||||
|
output += '/* TEAM */\n';
|
||||||
|
|
||||||
|
for (const group of this.toolData.team) {
|
||||||
|
let groupOutput = '';
|
||||||
|
for (const field of group) {
|
||||||
|
if (field.key.trim() !== '' && field.value.trim() !== '') {
|
||||||
|
groupOutput += `\t${field.key.trim()}: ${field.value.trim()}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (groupOutput !== '') {
|
||||||
|
output += groupOutput + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.toolData.thanks.length) {
|
||||||
|
output += '/* THANKS */\n';
|
||||||
|
|
||||||
|
for (const group of this.toolData.thanks) {
|
||||||
|
let groupOutput = '';
|
||||||
|
for (const field of group) {
|
||||||
|
if (field.key.trim() !== '' && field.value.trim() !== '') {
|
||||||
|
groupOutput += `\t${field.key.trim()}: ${field.value.trim()}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (groupOutput !== '') {
|
||||||
|
output += groupOutput + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.toolData.site.length) {
|
||||||
|
output += '/* SITE */\n';
|
||||||
|
for (const info of this.toolData.site) {
|
||||||
|
if (info.key.trim() !== '' && info.value.trim() !== '') {
|
||||||
|
output += `\t${info.key.trim()}: ${info.value.trim()}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toolResult = output;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 0 2px;
|
||||||
|
@apply text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 text-sm dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.humans-group {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
.humans-group:nth-child(odd) {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user