Skip to content

Commit

Permalink
WIP get page number and lowest section work
Browse files Browse the repository at this point in the history
  • Loading branch information
Theo-Hafsaoui committed Nov 17, 2024
1 parent 0820f7d commit 30acaec
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 19 deletions.
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

run:
echo "Not yet complete"

Expand All @@ -7,7 +6,6 @@ run-docker:

clean:
rm ./assets/latex/output/*
rm ./assets/latex/output/*

build:
go build
Expand Down
41 changes: 29 additions & 12 deletions internal/adapters/output/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,54 @@ import (
"log/slog"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"sync"
)


const COMPILER = "pdflatex"
var REGEX = regexp.MustCompile(`(\d+) page`)
type LatexCompiler struct{}

//Compile the template into PDF
func (*LatexCompiler) CompileTemplate(root string)error{
//Compile the templates into PDFs and return the number of page of the longest one
func (*LatexCompiler) CompileTemplate(root string)(int,error){
templates,err := getListOfTemplate(root);if err != nil {
return err
return 0,err
}
max_nb_of_page := 0
page_nb := make(chan int, len(templates))
var wg sync.WaitGroup
for _,template := range templates{
wg.Add(1)
go compile(template,root,&wg)
go compile(template,root,&wg, page_nb)
pdf_pages_nb := <-page_nb
max_nb_of_page = max(pdf_pages_nb,max_nb_of_page)
}
close(page_nb)
wg.Wait()
return nil
return max_nb_of_page,nil
}

//Compile the template into a pdf
func compile(template string, root string, wg* sync.WaitGroup){
defer wg.Done()
cmd := exec.Command(COMPILER,"-interaction=nonstopmode",
"-output-directory="+root+"/assets/latex/output", template )
log, err := cmd.Output(); if err != nil {
slog.Info("---FROM pdflatex ---\n"+string(log))
slog.Error("failed to compile file:"+template)
func compile(template string, root string, wg* sync.WaitGroup, c_page_nb chan int){
defer wg.Done()
cmd := exec.Command(COMPILER,"-interaction=nonstopmode",
"-output-directory="+root+"/assets/latex/output", template )
log, err := cmd.Output(); if err != nil {
slog.Warn("error(s) to compile file:"+template)
}
page_nb := -1
log_page := REGEX.FindStringSubmatch(string(log))
if len(log_page)<1{
slog.Error("failed to compile file didnt get the number of pages:"+template)
fmt.Println(log_page)
}else{
page_nb,err = strconv.Atoi(log_page[1]);if err != nil{
slog.Error(err.Error())}
}
c_page_nb <- page_nb
}

//Return the path of latex file inside the template directory
Expand Down
66 changes: 63 additions & 3 deletions internal/core/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,16 @@ func (s *CVService) GenerateTemplates()error{
generiqueTemplate,err := s.templateReader.ReadCVTemplate(s.root,params); if err != nil{
return err
}

for _, cv := range cvs {
err = generateCVFrom(cv,params,s.root,generiqueTemplate,s.templateProcessor)
if err != nil{
return err
}
}

err = s.compiler.CompileTemplate(s.root); if err != nil{ return err }
max_nb_page,err := s.compiler.CompileTemplate(s.root); if err != nil{ return err }
println("---")
println(max_nb_page)
println("---")
return nil
}

Expand All @@ -91,6 +92,7 @@ func generateCVFrom(cv CV, params Params, root string,
cvName := "CV-"+cv.Lang+"-"+vari+".tex"
slog.Info("Generating for:"+cvName)
cvTemplate := template

for _, section := range cv.Sections {
for _, paragraph := range section.Paragraphes {
headers := []string{ paragraph.H1, paragraph.H2,
Expand All @@ -108,6 +110,64 @@ func generateCVFrom(cv CV, params Params, root string,
return nil
}

//Sort items and after remove the last items
func sortAndRemoveLast(items []string, keywords []string) []string {
if len(items) == 0 {
return items
}
sortByScore(items, keywords)
return items[:len(items)-1]
}

//Return the index of the section from the CV with the lowest score
func getLowestSection(cv CV, keywords []string) int {
min_score := getScoreSection(cv.Sections[0],keywords)
min_idx := 0
for idx, section := range cv.Sections[1:] {
current_score := getScoreSection(section,keywords)
if current_score <= min_score{
min_idx = idx
min_score = current_score
}
}
return min_idx
}

//Return the index of the section from the CV with the lowest score
func getLowestParagraphe(section Section, keywords []string) int {
min_score := getScoreParagraphe(section.Paragraphes[0],keywords)
min_idx := 0
for idx, para := range section.Paragraphes[1:] {
current_score := getScoreParagraphe(para,keywords)
if current_score <= min_score{
min_idx = idx
min_score = current_score
}
}
return min_idx
}

//Get items of a section and sum they score to get global score of the items
func getScoreSection (section Section, keywords []string)int{
res := 0
for _, paragraph := range section.Paragraphes {
for _,item := range paragraph.Items{
res += getScore(item,keywords)
}
}
return res
}

//Get items of a single paragraph and sum they score to get global score of the items
func getScoreParagraphe (paragraph Paragraphe, keywords []string)int{
res := 0
for _,item := range paragraph.Items{
res += getScore(item,keywords)
}
return res
}


//Sorte a slice of items by the number of keyword
//
//The sort is done in ascending order as the section append work like a stack(Lifo)
Expand Down
196 changes: 195 additions & 1 deletion internal/core/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (s *MockParamsSource) GetParamsFrom(root string) (Params, error) {
}

type MockCompiler struct {}
func (c *MockCompiler) CompileTemplate(root string) error { return nil }
func (c *MockCompiler) CompileTemplate(root string) (int,error) { return 0,nil }

type MockSource struct {
CVs []CV
Expand Down Expand Up @@ -227,3 +227,197 @@ func TestSortByScore(t *testing.T) {
}
}
}


func TestSortAndRemoveLast(t *testing.T) {
keywords := []string{"foo", "bar"}
tests := []struct {
items []string
expected []string
}{
{
items: []string{" with foo", " with foo and bar", " with neither", " with bar"},
expected: []string{" with foo and bar", " with foo", " with bar"},
},
{
items: []string{" with foo bar foo bar", " with foo", " with bar bar bar", " with foo bar"},
expected: []string{" with foo bar foo bar", " with bar bar bar", " with foo bar"},
},
{
items: []string{" without keywords", " with bar", "Another without keywords"},
expected: []string{" with bar", " without keywords"},
},
{
items: []string{"single item"},
expected: []string{},
},
{
items: []string{},
expected: []string{},
},
}

for _, tt := range tests {
items := make([]string, len(tt.items))
copy(items, tt.items)
result := sortAndRemoveLast(items, keywords)

if len(result) != len(tt.expected) {
t.Errorf("expected length %v but got %v", len(tt.expected), len(result))
continue
}

for i := range result {
if result[i] != tt.expected[i] {
t.Errorf("expected %v but got %v", tt.expected, result)
break
}
}
}
}

func TestGetLowestSection(t *testing.T) {
keywords := []string{"experience", "skills", "projects"}
tests := []struct {
cv CV
expected int
}{
{
cv: CV{
Lang: "en",
Sections: []Section{
{
Title: "Work Experience",
Paragraphes: []Paragraphe{
{H1: "Experience 1", Items: []string{"experience", "project"}},
},
},
{
Title: "Education",
Paragraphes: []Paragraphe{
{H1: "Education 1", Items: []string{"education", "degree"}},
},
},
{
Title: "Skills",
Paragraphes: []Paragraphe{
{H1: "Skills", Items: []string{"skills", "knowledge"}},
},
},
},
},
expected: 0,
},
{
cv: CV{
Lang: "en",
Sections: []Section{
{
Title: "Skills",
Paragraphes: []Paragraphe{
{H1: "Technical Skills", Items: []string{"skills", "knowledge"}},
},
},
{
Title: "Projects",
Paragraphes: []Paragraphe{
{H1: "Project 1", Items: []string{"project", "skill"}},
},
},
{
Title: "Summary",
Paragraphes: []Paragraphe{
{H1: "Personal Summary", Items: []string{"summary"}},
},
},
},
},
expected: 1,
},
{
cv: CV{
Lang: "en",
Sections: []Section{
{
Title: "Summary",
Paragraphes: []Paragraphe{
{H1: "Summary", Items: []string{"introduction"}},
},
},
{
Title: "Skills",
Paragraphes: []Paragraphe{
{H1: "Skills", Items: []string{"skills"}},
},
},
},
},
expected: 0,
},
}

for _, tt := range tests {
result := getLowestSection(tt.cv, keywords)
if result != tt.expected {
t.Errorf("expected index %v but got %v", tt.expected, result)
}
}
}

func TestGetLowestParagraphe(t *testing.T) {
keywords := []string{"skills", "experience", "project"}
tests := []struct {
section Section
expected int
}{
{
section: Section{
Title: "Work Experience",
Paragraphes: []Paragraphe{
{H1: "Experience 1", Items: []string{"skills", "project"}},
{H1: "Experience 2", Items: []string{"experience", "skills"}},
{H1: "Experience 3", Items: []string{"project"}},
},
},
expected: 1,
},
{
section: Section{
Title: "Projects",
Paragraphes: []Paragraphe{
{H1: "Project A", Items: []string{"project", "skills"}},
{H1: "Project B", Items: []string{"skills", "experience"}},
{H1: "Project C", Items: []string{"project", "experience"}},
},
},
expected: 1,
},
{
section: Section{
Title: "Skills",
Paragraphes: []Paragraphe{
{H1: "Skillset 1", Items: []string{"skills", "tools", "project"}},
{H1: "Skillset 2", Items: []string{"experience", "skills"}},
},
},
expected: 0,
},
{
section: Section{
Title: "Summary",
Paragraphes: []Paragraphe{
{H1: "Summary", Items: []string{}},
{H1: "Overview", Items: []string{}},
},
},
expected: 0,
},
}

for _, tt := range tests {
result := getLowestParagraphe(tt.section, keywords)
if result != tt.expected {
t.Errorf("expected index %v but got %v", tt.expected, result)
}
}
}
2 changes: 1 addition & 1 deletion internal/core/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type ICVservice interface {
}

type Compiler interface {
CompileTemplate(root string) error
CompileTemplate(root string) (int,error)
}

type SourceParams interface {
Expand Down

0 comments on commit 30acaec

Please sign in to comment.