Merge branch '12-heuristic' into 'master'
Resolve "Структура классов для эвристических методов поиска определенных типов классов проекта" Closes #12 See merge request romanov73/git-extractor!8merge-requests/18/head
commit
b25a1dbab9
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.api;
|
||||
|
||||
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
||||
import ru.ulstu.extractor.heuristic.component.ProgrammingLanguage;
|
||||
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
import ru.ulstu.extractor.heuristic.service.DetectorService;
|
||||
import ru.ulstu.extractor.heuristic.service.ProgrammingLanguageService;
|
||||
import ru.ulstu.extractor.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ru.ulstu.extractor.heuristic.service.DetectorService.LangDetectScrupulousness.HIGH;
|
||||
import static ru.ulstu.extractor.heuristic.service.DetectorService.LangDetectScrupulousness.LOW;
|
||||
|
||||
public abstract class StructuralUnitIdentifier {
|
||||
public List<StructuralUnit> getEntityClasses(String projectPath, List<File> projectFiles, List<File> rootProjectFiles) {
|
||||
String subDirectory = getSourceDirectory(rootProjectFiles);
|
||||
return getEntityClasses(projectPath, subDirectory, projectFiles);
|
||||
}
|
||||
|
||||
public abstract boolean canAppliedToCode(String sourceCode);
|
||||
|
||||
public abstract boolean canAppliedToFile(File projectFile);
|
||||
|
||||
public abstract boolean canAppliedToProject(String projectPath, List<File> projectFiles, List<File> rootProjectFiles);
|
||||
|
||||
public abstract boolean isEntityClass(File file);
|
||||
|
||||
public abstract boolean isEntityClass(String sourceCode);
|
||||
|
||||
protected abstract boolean isBusinessLogicClass(File file);
|
||||
|
||||
public abstract List<StructuralUnit> getBusinessLogicClasses();
|
||||
|
||||
public abstract boolean isMultiModuleProject();
|
||||
|
||||
public abstract Optional<BuildTool> getBuildTool(List<File> rootDirectoryFiles);
|
||||
|
||||
protected abstract List<StructuralUnit> getEntityClasses(String projectPath, String subDirectory, List<File> projectFiles);
|
||||
|
||||
protected abstract String getSourceDirectory(List<File> rootProjectFiles);
|
||||
|
||||
protected abstract DetectorService getDetectorService();
|
||||
|
||||
protected abstract ProgrammingLanguageService getProgrammingLanguageService();
|
||||
|
||||
protected abstract ProgrammingLanguage getProgrammingLanguage();
|
||||
|
||||
protected Optional<ProgrammingLanguage> getMainProgrammingLanguage(String projectPath, List<File> projectFiles, List<File> rootProjectFiles) {
|
||||
String subDirectory = getSourceDirectory(rootProjectFiles);
|
||||
Map<ProgrammingLanguage, Integer> projectFileLanguageFrequency = new HashMap<>();
|
||||
projectFiles.stream()
|
||||
.filter(file -> StringUtils.fileInSubdirectory(file.getPath(), projectPath, subDirectory))
|
||||
.forEach(projectFile -> {
|
||||
Optional<ProgrammingLanguage> detectedLanguage = getMainProgrammingLanguage(projectFile, LOW);
|
||||
detectedLanguage.ifPresent(programmingLanguage -> projectFileLanguageFrequency.put(programmingLanguage, projectFileLanguageFrequency.getOrDefault(programmingLanguage, 0) + 1));
|
||||
});
|
||||
|
||||
Optional<Map.Entry<ProgrammingLanguage, Integer>> mostFrequentLanguageEntry = projectFileLanguageFrequency
|
||||
.entrySet()
|
||||
.stream()
|
||||
.max(Map.Entry.comparingByValue());
|
||||
if (mostFrequentLanguageEntry.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(mostFrequentLanguageEntry.get().getKey());
|
||||
}
|
||||
|
||||
protected Optional<ProgrammingLanguage> getMainProgrammingLanguage(File projectFile, DetectorService.LangDetectScrupulousness scrupulousness) {
|
||||
String fileContent = "";
|
||||
if (scrupulousness == HIGH) {
|
||||
try {
|
||||
fileContent = new String(Files.readAllBytes(projectFile.toPath()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return getProgrammingLanguageService().getByName(getDetectorService().getDetectedLanguage(
|
||||
projectFile.getName(),
|
||||
fileContent,
|
||||
scrupulousness));
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BuildTool {
|
||||
private final String name;
|
||||
|
||||
public BuildTool(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public abstract boolean canAppliedToProject(List<File> rootProjectFiles);
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public abstract String getSourceDirectoryPath();
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.component;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class GradleBuildTool extends BuildTool {
|
||||
|
||||
public GradleBuildTool() {
|
||||
super("Gradle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAppliedToProject(List<File> rootProjectFiles) {
|
||||
return rootProjectFiles.stream()
|
||||
.anyMatch(file -> file.getName().equals("build.gradle") || file.getName().equals("settings.gradle"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceDirectoryPath() {
|
||||
return "src";
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.component;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JavaProgrammingLanguage extends ProgrammingLanguage {
|
||||
public JavaProgrammingLanguage() {
|
||||
super("java");
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.component;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class MavenBuildTool extends BuildTool {
|
||||
|
||||
public MavenBuildTool() {
|
||||
super("Maven");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAppliedToProject(List<File> rootProjectFiles) {
|
||||
return rootProjectFiles.stream()
|
||||
.anyMatch(file -> file.getName().equals("pom.xml"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceDirectoryPath() {
|
||||
return "src";
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.component;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class ProgrammingLanguage {
|
||||
private final String name;
|
||||
|
||||
public ProgrammingLanguage(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean canMappedByName(String programmingLanguageName) {
|
||||
if (programmingLanguageName == null || programmingLanguageName.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
return getName().toLowerCase(Locale.ROOT).equals(programmingLanguageName.toLowerCase(Locale.ROOT))
|
||||
|| programmingLanguageName.toLowerCase(Locale.ROOT).contains(getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
import ru.ulstu.extractor.heuristic.service.StructuralUnitService;
|
||||
import ru.ulstu.extractor.service.GitRepositoryService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("StructuralUnitController")
|
||||
public class StructuralUnitController {
|
||||
private final StructuralUnitService structuralUnitService;
|
||||
private final GitRepositoryService gitRepositoryService;
|
||||
|
||||
public StructuralUnitController(StructuralUnitService structuralUnitService,
|
||||
GitRepositoryService gitRepositoryService) {
|
||||
this.structuralUnitService = structuralUnitService;
|
||||
this.gitRepositoryService = gitRepositoryService;
|
||||
}
|
||||
|
||||
@GetMapping("get-entities")
|
||||
public List<StructuralUnit> getEntities(String repositoryUrl) throws IOException {
|
||||
File rootPath = gitRepositoryService.getProjectDirectoryFile(repositoryUrl);
|
||||
return structuralUnitService.getEntities(rootPath);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.model;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class EntityUnit extends StructuralUnit {
|
||||
|
||||
public EntityUnit(String projectPath, File file) {
|
||||
super(projectPath, file);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.model;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static ru.ulstu.extractor.util.StringUtils.removePathPrefix;
|
||||
|
||||
public abstract class StructuralUnit {
|
||||
private final String pathToFile;
|
||||
private final String unitName;
|
||||
|
||||
public StructuralUnit(String projectPath, File file) {
|
||||
this.pathToFile = removePathPrefix(file.getPath(), projectPath);
|
||||
this.unitName = file.getName();
|
||||
}
|
||||
|
||||
public String getPathToFile() {
|
||||
return pathToFile;
|
||||
}
|
||||
|
||||
public String getUnitName() {
|
||||
return unitName;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class BuildToolService {
|
||||
private final List<BuildTool> buildTools;
|
||||
|
||||
public BuildToolService(List<BuildTool> buildTools) {
|
||||
this.buildTools = buildTools;
|
||||
}
|
||||
|
||||
public Optional<BuildTool> getProjectBuildTool(List<File> rootProjectFiles) {
|
||||
return buildTools.stream().filter(buildTool -> buildTool.canAppliedToProject(rootProjectFiles)).findAny();
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.service;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.DomElement;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static ru.ulstu.extractor.heuristic.service.DetectorService.LangDetectScrupulousness.LOW;
|
||||
|
||||
@Service
|
||||
public class DetectorService {
|
||||
public enum LangDetectScrupulousness {LOW, HIGH}
|
||||
|
||||
private final static String BASE_URL = "http://localhost:8080/lang-detector.html";
|
||||
|
||||
public String getDetectedLanguage(String fileName, String code, LangDetectScrupulousness scrupulousness) {
|
||||
if (scrupulousness == LOW) {
|
||||
return DirectoryService.getFileExtension(fileName).orElse("");
|
||||
}
|
||||
return getDetectedLanguage(code);
|
||||
}
|
||||
|
||||
private String getDetectedLanguage(String code) {
|
||||
String selectedLang = null;
|
||||
try (WebClient webClient = new WebClient()) {
|
||||
webClient.setJavaScriptTimeout(60 * 1000);
|
||||
webClient.getOptions().setThrowExceptionOnScriptError(false);
|
||||
final HtmlPage page = webClient.getPage(BASE_URL);
|
||||
DomElement codeElement = page.getElementById("input");
|
||||
codeElement.setTextContent(code);
|
||||
DomElement button = page.getElementById("btn");
|
||||
button.click();
|
||||
DomElement output = page.getElementById("output");
|
||||
String outputString = output.getTextContent();
|
||||
List<String> langsStrings = Arrays.asList(outputString.split("\n"));
|
||||
int max = 0;
|
||||
for (String langString : langsStrings) {
|
||||
int currentVal = Integer.parseInt(langString.split(":")[1].trim());
|
||||
if (currentVal > max) {
|
||||
max = currentVal;
|
||||
selectedLang = langString.split(":")[0].trim();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return selectedLang.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.service;
|
||||
|
||||
import com.github.javaparser.JavaParser;
|
||||
import com.github.javaparser.ParseResult;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.heuristic.api.StructuralUnitIdentifier;
|
||||
import ru.ulstu.extractor.heuristic.component.BuildTool;
|
||||
import ru.ulstu.extractor.heuristic.component.JavaProgrammingLanguage;
|
||||
import ru.ulstu.extractor.heuristic.component.ProgrammingLanguage;
|
||||
import ru.ulstu.extractor.heuristic.model.EntityUnit;
|
||||
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
import ru.ulstu.extractor.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ru.ulstu.extractor.heuristic.service.DetectorService.LangDetectScrupulousness.LOW;
|
||||
|
||||
@Service
|
||||
public class JavaIdentifier extends StructuralUnitIdentifier {
|
||||
private static final String ENTITY_ANNOTATION = "@Entity";
|
||||
private final DetectorService detectorService;
|
||||
private final BuildToolService buildToolService;
|
||||
private final ProgrammingLanguageService programmingLanguageService;
|
||||
|
||||
public JavaIdentifier(DetectorService detectorService,
|
||||
BuildToolService buildToolService,
|
||||
ProgrammingLanguageService programmingLanguageService) {
|
||||
this.detectorService = detectorService;
|
||||
this.buildToolService = buildToolService;
|
||||
this.programmingLanguageService = programmingLanguageService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAppliedToProject(String projectPath, List<File> projectFiles, List<File> rootProjectFiles) {
|
||||
return /*getBuildTool() instanceof GradleBuildTool
|
||||
&&*/ getMainProgrammingLanguage(projectPath, projectFiles, rootProjectFiles).orElse(null) instanceof JavaProgrammingLanguage;
|
||||
}
|
||||
|
||||
public boolean canAppliedToFile(File projectFile) {
|
||||
return getMainProgrammingLanguage(projectFile, LOW).orElse(null) instanceof JavaProgrammingLanguage;
|
||||
}
|
||||
|
||||
public boolean canAppliedToCode(String sourceCode) {
|
||||
return getMainProgrammingLanguage(sourceCode).orElse(null) instanceof JavaProgrammingLanguage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructuralUnit> getEntityClasses(String projectPath, String subDirectory, List<File> projectFiles) {
|
||||
return projectFiles.stream()
|
||||
.filter(file -> StringUtils.fileInSubdirectory(file.getPath(), projectPath, subDirectory))
|
||||
.filter(this::isEntityClass)
|
||||
.map(file -> new EntityUnit(projectPath, file))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected Optional<ProgrammingLanguage> getMainProgrammingLanguage(String sourceCode) {
|
||||
return sourceCodeContainsClass(sourceCode)
|
||||
? Optional.of(getProgrammingLanguage())
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructuralUnit> getBusinessLogicClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiModuleProject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BuildTool> getBuildTool(List<File> rootDirectoryFiles) {
|
||||
return buildToolService.getProjectBuildTool(rootDirectoryFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DetectorService getDetectorService() {
|
||||
return detectorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProgrammingLanguageService getProgrammingLanguageService() {
|
||||
return programmingLanguageService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProgrammingLanguage getProgrammingLanguage() {
|
||||
return new JavaProgrammingLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityClass(File file) {
|
||||
try {
|
||||
return file.getName().endsWith("java") && classContainsAnnotation(file, ENTITY_ANNOTATION);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityClass(String sourceCode) {
|
||||
try {
|
||||
return classContainsAnnotation(sourceCode, ENTITY_ANNOTATION);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean classContainsAnnotation(File file, String annotationDeclaration) throws IOException {
|
||||
return classContainsAnnotation(new String(Files.readAllBytes(file.toPath())), annotationDeclaration);
|
||||
}
|
||||
|
||||
private boolean classContainsAnnotation(String sourceCode, String annotationDeclaration) {
|
||||
JavaParser parser = new JavaParser();
|
||||
ParseResult<CompilationUnit> parseResult = parser.parse(sourceCode);
|
||||
if (parseResult.getResult().isPresent() && parseResult.getResult().get().findCompilationUnit().isPresent()) {
|
||||
return parseResult.getResult().get().getTypes().stream()
|
||||
.anyMatch(clazz -> clazz.getAnnotations().stream().anyMatch(annotation -> annotation.toString().startsWith(annotationDeclaration)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean sourceCodeContainsClass(String sourceCode) {
|
||||
JavaParser parser = new JavaParser();
|
||||
ParseResult<CompilationUnit> parseResult = parser.parse(sourceCode);
|
||||
if (parseResult.getResult().isPresent() && parseResult.getResult().get().findCompilationUnit().isPresent()) {
|
||||
return parseResult.getResult().get().getTypes().stream().findAny().isPresent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSourceDirectory(List<File> rootDirectoryFiles) {
|
||||
return buildToolService.getProjectBuildTool(rootDirectoryFiles)
|
||||
.map(BuildTool::getSourceDirectoryPath)
|
||||
.orElse("src");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isBusinessLogicClass(File file) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.heuristic.component.ProgrammingLanguage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class ProgrammingLanguageService {
|
||||
private final List<ProgrammingLanguage> programmingLanguages;
|
||||
|
||||
public ProgrammingLanguageService(List<ProgrammingLanguage> programmingLanguages) {
|
||||
this.programmingLanguages = programmingLanguages;
|
||||
}
|
||||
|
||||
public Optional<ProgrammingLanguage> getByName(String programmingLanguageName) {
|
||||
return programmingLanguages.stream().filter(lang -> lang.canMappedByName(programmingLanguageName)).findAny();
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.heuristic.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.heuristic.api.StructuralUnitIdentifier;
|
||||
import ru.ulstu.extractor.heuristic.model.StructuralUnit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Service
|
||||
public class StructuralUnitService {
|
||||
private final DirectoryService directoryService;
|
||||
private final List<StructuralUnitIdentifier> structuralUnitIdentifiers;
|
||||
|
||||
public StructuralUnitService(DirectoryService directoryService,
|
||||
List<StructuralUnitIdentifier> structuralUnitIdentifiers) {
|
||||
this.directoryService = directoryService;
|
||||
this.structuralUnitIdentifiers = structuralUnitIdentifiers;
|
||||
}
|
||||
|
||||
public List<StructuralUnit> getEntities(File rootPath) throws IOException {
|
||||
List<File> projectFiles = directoryService.getFilesRecursively(rootPath);
|
||||
List<File> rootProjectFiles = directoryService.getDirectoryFiles(rootPath.toPath());
|
||||
return getStructuralUnitIdentifier(
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToProject(
|
||||
rootPath.getPath(),
|
||||
projectFiles,
|
||||
rootProjectFiles))
|
||||
.orElseThrow(() -> new RuntimeException("Identifier not found"))
|
||||
.getEntityClasses(rootPath.getPath(), projectFiles, rootProjectFiles);
|
||||
}
|
||||
|
||||
public boolean containsEntity(File projectFile) {
|
||||
return getStructuralUnitIdentifier(
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToFile(projectFile))
|
||||
.map(identifier -> identifier.isEntityClass(projectFile))
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
public boolean containsEntity(String sourceCode) {
|
||||
return getStructuralUnitIdentifier(
|
||||
structuralUnitIdentifier -> structuralUnitIdentifier.canAppliedToCode(sourceCode))
|
||||
.map(identifier -> identifier.isEntityClass(sourceCode))
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
private Optional<StructuralUnitIdentifier> getStructuralUnitIdentifier(Predicate<StructuralUnitIdentifier> predicate) {
|
||||
return structuralUnitIdentifiers.stream()
|
||||
.filter(predicate)
|
||||
.findAny();
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*/
|
||||
|
||||
package ru.ulstu.extractor.util;
|
||||
|
||||
import java.nio.file.FileSystems;
|
||||
|
||||
public class StringUtils {
|
||||
public final static String EMPTY_STRING = "";
|
||||
private final static String PATH_SEPARATOR = FileSystems.getDefault().getSeparator();
|
||||
|
||||
public static String addPathSeparator(String path) {
|
||||
return path + PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
public static String removePathPrefix(String path, String prefix) {
|
||||
if (prefix.endsWith(PATH_SEPARATOR)) {
|
||||
return path.replace(prefix, EMPTY_STRING);
|
||||
}
|
||||
return path.replace(addPathSeparator(prefix), EMPTY_STRING);
|
||||
}
|
||||
|
||||
public static boolean fileInSubdirectory(String filePath, String projectPath, String subDirectory) {
|
||||
return filePath.startsWith(projectPath + PATH_SEPARATOR + subDirectory);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
~ You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
-->
|
||||
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
<changeSet author="orion" id="20210412-100000-1">
|
||||
<addColumn tableName="file_change">
|
||||
<column name="contains_entity" type="boolean"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
@ -0,0 +1,30 @@
|
||||
.error-popup-container {
|
||||
background: #999999;
|
||||
width: 600px;
|
||||
max-width: 85vw;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
font-size: 25px;
|
||||
position: fixed;
|
||||
box-shadow: 0px 0px 100px #999999;
|
||||
border-radius: 60px;
|
||||
border: 1px solid black;
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
.error-popup-message {
|
||||
color: #690000;
|
||||
font-weight: bold;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.more-games-logo {
|
||||
position: absolute;
|
||||
margin: 8px;
|
||||
z-index: 100000000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 845 B |
@ -0,0 +1,84 @@
|
||||
/* globals hljs */
|
||||
|
||||
var allLanguages = hljs.listLanguages();
|
||||
var commonLanguages = ["cpp", "cs", "css", "javascript", "java", "objectivec", "perl", "php", "python", "ruby", "sql", "xml", "autohotkey", "lua", "actionscript", "swift", "vbscript"];
|
||||
var highlightResult;
|
||||
document.getElementById("commonLanguageTitle").title = commonLanguages.toString().replace(/,/g, ", ");
|
||||
|
||||
document.getElementById("highlight").onclick = function() {
|
||||
var code = document.getElementById("pasteCode").value;
|
||||
document.getElementById("languageOutput").hidden = true;
|
||||
document.getElementById("option2").hidden = true;
|
||||
document.getElementById("option2Languages").hidden = true;
|
||||
document.getElementById("option2SelectTd").hidden = true;
|
||||
document.getElementById("option2Select").disabled = false;
|
||||
document.getElementById("option2Select").innerText = "Select";
|
||||
document.getElementById("highlightCode").innerHTML = "";
|
||||
document.getElementById("highlightCode").className = "";
|
||||
document.getElementById("option1Select").onclick = null;
|
||||
document.getElementById("option2Select").onclick = null;
|
||||
document.getElementById("error").hidden = true;
|
||||
|
||||
if (document.getElementById("commonLanguagesOnly").checked) {
|
||||
highlightResult = hljs.highlightAuto(code, commonLanguages);
|
||||
} else {
|
||||
highlightResult = hljs.highlightAuto(code, allLanguages);
|
||||
}
|
||||
|
||||
if (typeof highlightResult.language != "undefined") {
|
||||
document.getElementById("highlightCode").innerHTML = highlightResult.value;
|
||||
|
||||
document.getElementById("pasteCode").value = "";
|
||||
var languageObj = hljs.getLanguage(highlightResult.language);
|
||||
var languages = [];
|
||||
if (typeof languageObj.aliases != "undefined") {
|
||||
languages = languageObj.aliases.slice();
|
||||
}
|
||||
languages.unshift(highlightResult.language);
|
||||
|
||||
document.getElementById("languageOutput").hidden = false;
|
||||
document.getElementById("option1Languages").innerText = languages.toString().replace(/,/g, ", ");
|
||||
document.getElementById("option1Select").disabled = true;
|
||||
document.getElementById("option1Select").innerText = "Selected";
|
||||
document.getElementById("option1Select").onclick = function() {
|
||||
document.getElementById("option1Select").disabled = true;
|
||||
document.getElementById("option1Select").innerText = "Selected";
|
||||
document.getElementById("option2Select").disabled = false;
|
||||
document.getElementById("option2Select").innerText = "Select";
|
||||
document.getElementById("highlightCode").innerHTML = highlightResult.value;
|
||||
};
|
||||
|
||||
if (typeof highlightResult.second_best != "undefined") {
|
||||
var languageObj = hljs.getLanguage(highlightResult.second_best.language);
|
||||
var languages = [];
|
||||
if (typeof languageObj.aliases != "undefined") {
|
||||
languages = languageObj.aliases.slice();
|
||||
}
|
||||
languages.unshift(highlightResult.second_best.language);
|
||||
document.getElementById("option2Languages").innerText = languages.toString().replace(/,/g, ", ");
|
||||
document.getElementById("option2Select").onclick = function() {
|
||||
document.getElementById("option1Select").disabled = false;
|
||||
document.getElementById("option1Select").innerText = "Select";
|
||||
document.getElementById("option2Select").disabled = true;
|
||||
document.getElementById("option2Select").innerText = "Selected";
|
||||
document.getElementById("highlightCode").innerHTML = highlightResult.second_best.value;
|
||||
};
|
||||
document.getElementById("option2").hidden = false;
|
||||
document.getElementById("option2Languages").hidden = false;
|
||||
document.getElementById("option2SelectTd").hidden = false;
|
||||
}
|
||||
|
||||
document.getElementById("highlightCode").className = "hljs";
|
||||
} else {
|
||||
document.getElementById("error").hidden = false;
|
||||
if (document.getElementById("pasteCode").value.length == 0) {
|
||||
document.getElementById("error").innerText = "Error: No code entered. Please paste your code above and try again.";
|
||||
} else {
|
||||
if (document.getElementById("commonLanguagesOnly").checked) {
|
||||
document.getElementById("error").innerText = 'Error: Unable to identify the programming language. Please add more code or uncheck the "Common Languages Only" option.';
|
||||
} else {
|
||||
document.getElementById("error").innerText = "Error: Unable to identify the programming language. Please add more code to increase the accuracy of the detection.";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Visual Studio 2015 dark style
|
||||
* Author: Nicolas LLOBERA <nllobera@gmail.com>
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #1E1E1E;
|
||||
color: #DCDCDC;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-name {
|
||||
color: #569CD6;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
color: #569CD6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-type {
|
||||
color: #4EC9B0;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-class {
|
||||
color: #B8D7A3;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-meta-string {
|
||||
color: #D69D85;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-template-tag {
|
||||
color: #9A5334;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
.hljs-function,
|
||||
.hljs-title,
|
||||
.hljs-params,
|
||||
.hljs-formula {
|
||||
color: #DCDCDC;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #57A64A;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag {
|
||||
color: #608B4E;
|
||||
}
|
||||
|
||||
.hljs-meta,
|
||||
.hljs-meta-keyword,
|
||||
.hljs-tag {
|
||||
color: #9B9B9B;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #BD63C5;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-attribute,
|
||||
.hljs-builtin-name {
|
||||
color: #9CDCFE;
|
||||
}
|
||||
|
||||
.hljs-section {
|
||||
color: gold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*.hljs-code {
|
||||
font-family:'Monospace';
|
||||
}*/
|
||||
|
||||
.hljs-bullet,
|
||||
.hljs-selector-tag,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #D7BA7D;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #144212;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #600;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- saved from url=(0050)https://creativetechguy.com/utilities/codedetector -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
<meta name="keywords"
|
||||
content="programming, language, detector, identifier, highlighter, syntax, code, ctg, Creative Tech Guy, Jason O'Neill">
|
||||
<meta name="description" content="Automatically detect a programming language by pasting a snippet of code.">
|
||||
<meta name="author" content="Jason O'Neill">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Code Detector & Formatter</title>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://creativetechguy.com/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="https://creativetechguy.com/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="https://creativetechguy.com/favicon-16x16.png">
|
||||
<link rel="manifest" href="https://creativetechguy.com/manifest.json">
|
||||
<link rel="mask-icon" href="https://creativetechguy.com/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="https://creativetechguy.com/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="Code Detector">
|
||||
<meta name="application-name" content="Code Detector">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<meta property="og:title" content="Code Detector & Formatter">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:locale" content="en_US">
|
||||
<meta property="og:url" content="https://creativetechguy.com/utilities/codedetector">
|
||||
<meta property="og:description" content="Automatically detect a programming language by pasting a snippet of code.">
|
||||
<meta property="og:image" content="https://creativetechguy.com/images/logo.png">
|
||||
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@JasonONeillCTG">
|
||||
<meta name="twitter:title" content="Code Detector & Formatter">
|
||||
<meta name="twitter:description"
|
||||
content="Automatically detect a programming language by pasting a snippet of code.">
|
||||
<meta name="twitter:image" content="https://creativetechguy.com/images/logo.png">
|
||||
|
||||
<link rel="stylesheet" href="./Code Detector & Formatter_files/games.css" type="text/css">
|
||||
<link rel="stylesheet" href="./Code Detector & Formatter_files/vs2015.css">
|
||||
<style>
|
||||
table, tbody, tr, th, td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th {
|
||||
border-bottom: 2px solid black;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.center,
|
||||
.center * {
|
||||
text-align: center;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://creativetechguy.com/utilities" id="homeLogo" title="Back to Utilities">
|
||||
<img src="./Code Detector & Formatter_files/more arrow.png" class="more-games-logo" alt="More Utilities">
|
||||
</a>
|
||||
<div class="center">
|
||||
<h1 style="margin-top: 0px;">Code Detector & Formatter</h1>
|
||||
<p>Paste code below and click "Detect Code" to format and analyze the code snippet.<br>The more code that is
|
||||
included, the more accurate the analysis will be.</p>
|
||||
<textarea id="pasteCode"
|
||||
style="width: 100%; max-width: 600px; height: 350px; text-align: left; resize: vertical; box-sizing: border-box;"></textarea><br>
|
||||
<div id="commonLanguageTitle"
|
||||
title="cpp, cs, css, javascript, java, objectivec, perl, php, python, ruby, sql, xml, autohotkey, lua, actionscript, swift, vbscript">
|
||||
Common Languages Only: <input type="checkbox" id="commonLanguagesOnly" checked=""><br>
|
||||
</div>
|
||||
<button id="highlight">Detect Code</button>
|
||||
<br>
|
||||
<br>
|
||||
<p id="error" hidden=""></p>
|
||||
<table id="languageOutput" hidden="">
|
||||
<tbody style="text-align: center;">
|
||||
<tr>
|
||||
<th id="option1">Option 1</th>
|
||||
<th id="option2">Option 2</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="option1Languages"></td>
|
||||
<td id="option2Languages"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="option1SelectTd" style="width: 100px;">
|
||||
<button id="option1Select">Select</button>
|
||||
</td>
|
||||
<td id="option2SelectTd" style="width: 100px;">
|
||||
<button id="option2Select">Select</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<pre><code id="highlightCode" style="max-height: 400px; overflow: auto;"></code></pre>
|
||||
<hr style="border-color:#000000; border-top-width: 5px; border-style: solid; height: 0px; margin-top: 4px; max-width: 600px;">
|
||||
<p style="font-size: 12px; margin: 5px; text-align: center;">Powered by <a href="https://highlightjs.org/"
|
||||
target="_blank"
|
||||
rel="noopener">highlight.js</a><br>Copyright
|
||||
<span id="copyrightYear">2021</span> Jason O'Neill</p>
|
||||
<script>
|
||||
document.getElementById("copyrightYear").innerText = new Date().getFullYear();
|
||||
|
||||
</script>
|
||||
|
||||
<script src="./Code Detector & Formatter_files/highlight.pack.js.Без названия"></script>
|
||||
<script src="./Code Detector & Formatter_files/script.js.Без названия"></script>
|
||||
<noscript>
|
||||
<div class="error-popup-container">
|
||||
<p class="error-popup-message">This page, along with all of my other web games and utilities, require
|
||||
JavaScript.<br>Please enable JavaScript in your browser and refresh to continue.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
</body>
|
||||
<style id="stylish-1" class="stylish" type="text/css">td, div {
|
||||
font-family: arial, sans-serif !important;
|
||||
}</style>
|
||||
</html>
|
@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- saved from url=(0041)https://hosein2398.github.io/lang-detect/ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
<title>lang-detector</title>
|
||||
<script defer="" src="bundle.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a target="_blank" title="lang-detector on github" href="https://github.com/ts95/lang-detector" class="github-corner">
|
||||
<svg width="80" height="80" viewBox="0 0 250 250" style="position: absolute; top: 0; border: 0; right: 0;">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
||||
fill="white" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
||||
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
|
||||
fill="white" class="octo-body"></path>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
|
||||
<h1 id="title">lang-detector <a target="_blank" title="lang-detector on github"
|
||||
href="https://github.com/ts95/lang-detector"><img src="lang-detector.svg"></a>
|
||||
</h1>
|
||||
|
||||
<div class="wrapper">
|
||||
<textarea id="input" autofocus="" placeholder="Write some code to detect here."></textarea>
|
||||
|
||||
<button id="btn">Detect</button>
|
||||
<pre id="output" disabled="">JavaScript: 0
|
||||
C: 3
|
||||
C++: 3
|
||||
Python: 0
|
||||
Java: 8
|
||||
HTML: 0
|
||||
CSS: 0
|
||||
Ruby: 2
|
||||
Go: 0
|
||||
PHP: 2
|
||||
Unknown: 1</pre>
|
||||
</div>
|
||||
|
||||
<footer class="copyright">Toni Sučić ©</footer>
|
||||
|
||||
<style>
|
||||
@import url(http://fonts.googleapis.com/css?family=Roboto:700,400,300);
|
||||
|
||||
body {
|
||||
margin: 20px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
textarea {
|
||||
color: #555;
|
||||
font-size: 1em;
|
||||
width: 600px;
|
||||
height: 200px;
|
||||
border: 4px solid #eee;
|
||||
padding: 10px;
|
||||
outline: none;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
textarea,
|
||||
textarea[disabled] {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
pre {
|
||||
color: #555;
|
||||
font-size: 1em;
|
||||
width: 600px;
|
||||
height: 150px;
|
||||
border: 4px solid #eee;
|
||||
padding: 10px;
|
||||
outline: none;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #999;
|
||||
background: none;
|
||||
border: 4px solid #eee;
|
||||
padding: 7px 12px 7px 12px;
|
||||
margin: 0;
|
||||
font-size: 1.2em;
|
||||
outline: none;
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.butt {
|
||||
text-align: center;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
color: #777;
|
||||
cursor: pointer;
|
||||
border: 4px solid #ccc;
|
||||
}
|
||||
|
||||
button:active {
|
||||
color: #555;
|
||||
background-color: #f8f8f8;
|
||||
border: 4px solid #bbb;
|
||||
}
|
||||
|
||||
#title {
|
||||
color: #aaa;
|
||||
font-size: 2.5em;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#input {
|
||||
resize: none;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#output {
|
||||
resize: none;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
height: auto;
|
||||
font-size: 22px
|
||||
}
|
||||
|
||||
#btn {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
color: #bbb;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</body>
|
||||
<style id="stylish-1" class="stylish" type="text/css">td, div {
|
||||
font-family: arial, sans-serif !important;
|
||||
}</style>
|
||||
</html>
|
@ -0,0 +1,32 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="76" height="20">
|
||||
<style>a:hover #llink{fill:url(#b);stroke:#ccc}a:hover #rlink{fill:#4183c4}</style>
|
||||
<linearGradient id="a" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#fcfcfc" stop-opacity="0"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#ccc" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<g stroke="#d5d5d5">
|
||||
<rect stroke="none" fill="#fcfcfc" x="0.5" y="0.5" width="48" height="19" rx="2"/>
|
||||
<rect x="54.5" y="0.5" width="21" height="19" rx="2" fill="#fafafa"/>
|
||||
<rect x="54" y="7.5" width="0.5" height="5" stroke="#fafafa"/>
|
||||
<path d="M54.5 6.5 l-3 3v1 l3 3" stroke="d5d5d5" fill="#fafafa"/>
|
||||
</g>
|
||||
<image x="5" y="3" width="14" height="14"
|
||||
xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMTgxNzE3IiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViIGljb248L3RpdGxlPjxwYXRoIGQ9Ik0xMiAuMjk3Yy02LjYzIDAtMTIgNS4zNzMtMTIgMTIgMCA1LjMwMyAzLjQzOCA5LjggOC4yMDUgMTEuMzg1LjYuMTEzLjgyLS4yNTguODItLjU3NyAwLS4yODUtLjAxLTEuMDQtLjAxNS0yLjA0LTMuMzM4LjcyNC00LjA0Mi0xLjYxLTQuMDQyLTEuNjFDNC40MjIgMTguMDcgMy42MzMgMTcuNyAzLjYzMyAxNy43Yy0xLjA4Ny0uNzQ0LjA4NC0uNzI5LjA4NC0uNzI5IDEuMjA1LjA4NCAxLjgzOCAxLjIzNiAxLjgzOCAxLjIzNiAxLjA3IDEuODM1IDIuODA5IDEuMzA1IDMuNDk1Ljk5OC4xMDgtLjc3Ni40MTctMS4zMDUuNzYtMS42MDUtMi42NjUtLjMtNS40NjYtMS4zMzItNS40NjYtNS45MyAwLTEuMzEuNDY1LTIuMzggMS4yMzUtMy4yMi0uMTM1LS4zMDMtLjU0LTEuNTIzLjEwNS0zLjE3NiAwIDAgMS4wMDUtLjMyMiAzLjMgMS4yMy45Ni0uMjY3IDEuOTgtLjM5OSAzLS40MDUgMS4wMi4wMDYgMi4wNC4xMzggMyAuNDA1IDIuMjgtMS41NTIgMy4yODUtMS4yMyAzLjI4NS0xLjIzLjY0NSAxLjY1My4yNCAyLjg3My4xMiAzLjE3Ni43NjUuODQgMS4yMyAxLjkxIDEuMjMgMy4yMiAwIDQuNjEtMi44MDUgNS42MjUtNS40NzUgNS45Mi40Mi4zNi44MSAxLjA5Ni44MSAyLjIyIDAgMS42MDYtLjAxNSAyLjg5Ni0uMDE1IDMuMjg2IDAgLjMxNS4yMS42OS44MjUuNTdDMjAuNTY1IDIyLjA5MiAyNCAxNy41OTIgMjQgMTIuMjk3YzAtNi42MjctNS4zNzMtMTItMTItMTIiLz48L3N2Zz4="/>
|
||||
<g aria-hidden="false" fill="#333" text-anchor="middle" font-family="Helvetica Neue,Helvetica,Arial,sans-serif"
|
||||
text-rendering="geometricPrecision" font-weight="700" font-size="110px" line-height="14px">
|
||||
<a target="_blank" xlink:href="https://github.com/ts95/lang-detector">
|
||||
<text aria-hidden="true" x="325" y="150" fill="#fff" transform="scale(.1)" textLength="210">Star</text>
|
||||
<text x="325" y="140" transform="scale(.1)" textLength="210">Star</text>
|
||||
<rect id="llink" stroke="#d5d5d5" fill="url(#a)" x=".5" y=".5" width="48" height="19" rx="2"/>
|
||||
</a>
|
||||
<a target="_blank" xlink:href="https://github.com/ts95/lang-detector/stargazers">
|
||||
<rect width="22" x="54" height="20" fill="rgba(0,0,0,0)"/>
|
||||
<text aria-hidden="true" x="645" y="150" fill="#fff" transform="scale(.1)" textLength="130">28</text>
|
||||
<text id="rlink" x="645" y="140" transform="scale(.1)" textLength="130">28</text>
|
||||
</a>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
Loading…
Reference in New Issue