package converters import ( "fmt" "strings" "github.com/medium.rip/pkg/entities" ) const IMAGE_HOST = "https://cdn-images-1.medium.com/fit/c" const MAX_WIDTH = 800 const FALLBACK_HEIGHT = 600 type Image struct { ID string OriginalHeight int64 OriginalWidth int64 } func (i *Image) Initialize(originalWidth *int64, originalHeight *int64) { if originalWidth != nil { i.OriginalWidth = *originalWidth } else { i.OriginalWidth = MAX_WIDTH } if originalHeight != nil { i.OriginalHeight = *originalHeight } else { i.OriginalHeight = FALLBACK_HEIGHT } } func (i *Image) width() int64 { if i.OriginalWidth > MAX_WIDTH { return MAX_WIDTH } else { return i.OriginalWidth } } func (i *Image) src() string { return fmt.Sprintf("%s/%d/%d/%s", IMAGE_HOST, i.width(), i.height(), i.ID) } func (i *Image) height() int64 { if i.OriginalWidth > MAX_WIDTH { return i.OriginalHeight * int64(i.ratio()) } else { return i.OriginalHeight } } func (i *Image) ratio() float32 { return float32(MAX_WIDTH) / float32(i.OriginalWidth) } func ConvertParagraphs(paragraphs []entities.Paragraph) string { if len(paragraphs) == 0 { return "" } var ps strings.Builder skipCount := 0 for i, p := range paragraphs { if skipCount > 0 { skipCount-- continue } switch p.Type { case "BQ", "MIXTAPE_EMBED", "PQ": children := ConvertMarkup(p.Text, p.Markups) ps.WriteString(fmt.Sprintf("

%s

", children)) case "H2": children := ConvertMarkup(p.Text, p.Markups) if p.Name != "" { ps.WriteString(fmt.Sprintf("

%s

", p.Name, children)) } else { ps.WriteString(fmt.Sprintf("

%s

", children)) } case "H3": children := ConvertMarkup(p.Text, p.Markups) if p.Name != "" { ps.WriteString(fmt.Sprintf("

%s

", p.Name, children)) } else { ps.WriteString(fmt.Sprintf("

%s

", children)) } case "H4": children := ConvertMarkup(p.Text, p.Markups) if p.Name != "" { ps.WriteString(fmt.Sprintf("

%s

", p.Name, children)) } else { ps.WriteString(fmt.Sprintf("

%s

", children)) } // TODO: handle IFRAME case "IMG": ps.WriteString(convertImg(p)) case "OLI": listItems, skip := convertOli(paragraphs[i:]) skipCount = skip ps.WriteString(fmt.Sprintf("
    %s
", listItems)) case "ULI": listItems, skip := convertUli(paragraphs[i:]) skipCount = skip ps.WriteString(fmt.Sprintf("", listItems)) case "P": children := ConvertMarkup(p.Text, p.Markups) ps.WriteString(fmt.Sprintf("

%s

", children)) case "PRE": children := ConvertMarkup(p.Text, p.Markups) ps.WriteString(fmt.Sprintf("
%s
", children)) case "SECTION_CAPTION": // unused default: } } return ps.String() } func convertImg(p entities.Paragraph) string { if p.Metadata != nil { captionMarkup := ConvertMarkup(p.Text, p.Markups) img := Image{ID: p.Metadata.ID} img.Initialize(&p.Metadata.OriginalWidth, &p.Metadata.OriginalHeight) return fmt.Sprintf("
%s
", img.src(), img.width(), captionMarkup) } else { return "" } } func convertOli(ps []entities.Paragraph) (string, int) { var sb strings.Builder count := 0 for _, p := range ps { if p.Type == "OLI" { children := ConvertMarkup(p.Text, p.Markups) sb.WriteString(fmt.Sprintf("
  • %s
  • ", children)) count++ } else { break } } return sb.String(), count } func convertUli(ps []entities.Paragraph) (string, int) { var sb strings.Builder count := 0 for _, p := range ps { if p.Type == "ULI" { children := ConvertMarkup(p.Text, p.Markups) sb.WriteString(fmt.Sprintf("
  • %s
  • ", children)) count++ } else { break } } return sb.String(), count }