일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Flutter
- 공자명언
- 이모지
- FSM
- Streaming
- 오픈소스
- Freesound
- Firebase
- recyclerview
- Android
- 좋은글필사하기
- 이모지메모
- 1인개발자
- DART
- ASMR
- bash
- 넷플릭스
- kotlin
- 명언모음
- Linux
- androidx
- 코틀린
- 파이썬
- 공부집중
- 명심보감
- 소울칼리버6
- jetpack compose
- 벤자민플랭클린
- 장자명언
- Coroutine
Archives
- Today
- Total
Vintage appMaker의 Tech Blog
[Flutter] dart로 opml 파싱 본문
dart를 이용한 간단한 opml 제어
opml(Outline Processor Markup Language)은 구조적 글씨기에 사용되는 XML의 확장문법이다.
dart에서는 opml을 파싱, 생성할 수 있는 opml 패키지를 제공한다.
다음 예제는 다음과 같다.
- opml 문서를 파싱하는 하여 HTML로 만드는 예제
- opml을 코드로 만드는 예제
- 생성
dart create opmltest
- 설치
dart pub add opml
dart pub add markdown
- 예제 - opmltest.dart
import 'dart:io';
import 'package:markdown/markdown.dart';
import 'package:opml/opml.dart';
// 간단한 Outlline용 tag 만들기
class OutlineHTML {
int indent = 1;
StringBuffer sBuff = StringBuffer();
// text를 추가
void addText(String s) {
String htmlStr = extractMarkDownToHtml(s);
sBuff.writeln('${makeOutline(indent)} $htmlStr <br>');
}
// 필요한 HTML만 추출한다.
String extractMarkDownToHtml(String s) {
String htmlStr = markdownToHtml(s);
htmlStr = htmlStr.replaceAll("<p>", "");
htmlStr = htmlStr.replaceAll("</p>", "");
htmlStr = htmlStr.replaceAll("<ol>", "");
htmlStr = htmlStr.replaceAll("</ol>", "");
htmlStr = htmlStr.replaceAll("<li>", "");
htmlStr = htmlStr.replaceAll("</li>", "");
htmlStr = htmlStr.replaceAll("</li>", "");
htmlStr = htmlStr.replaceAll(RegExp(r'<ol\s[^>]*>'), '');
return htmlStr;
}
// title 추가
void addTitle(String s) {
sBuff.writeln('<h1>$s</h1>');
}
// 첫번째 depth의 제목
void addCategory(String s) {
sBuff.writeln('<h4>$s</h4>');
}
// 아웃라인 만들기
String makeOutline(int indx) {
String s = "   " * indent;
return (indent == 0) ? s : "$s-";
}
@override
String toString() {
return sBuff.toString();
}
}
void main() {
print('======> Read Example_in.xml to HTML');
readExample();
print('======> Write example_out.xml(make OPML with code)');
writeSimpleOPML();
}
OutlineHTML html = OutlineHTML();
// 재귀적으로 child를 찾아서 출력
void readChildren(OpmlOutline category) {
html.addText(category.text!);
for (var feed in category.children!) {
html.indent++;
readChildren(feed);
html.indent--;
}
}
// OPML에서 값을 읽어온다.
void readExample() {
final xml = File('./example_in.xml').readAsStringSync();
final doc = OpmlDocument.parse(xml);
html.addTitle('${doc.head.title}');
for (var category in doc.body) {
html.addCategory('▪ ${category.text}');
for (var feed in category.children!) {
readChildren(feed);
}
}
writeHTML(html.toString());
}
// Write Simple 예제
void writeSimpleOPML() {
final head = OpmlHeadBuilder().title('Example Export').build();
final body = <OpmlOutline>[];
body.add(OpmlOutlineBuilder()
.text('입력되는 내용')
.title('타이틀')
.addChild(OpmlOutlineBuilder()
.type('text')
.text('1.보여지는 텍스트')
.title('Title일 뿐')
.addChild(OpmlOutlineBuilder().text("👋 자식항목").title('').build())
.build())
.addChild(OpmlOutlineBuilder()
.type('text')
.text('2. 두번째 텍스트')
.title('Title일 뿐')
.build())
.build());
[for (int i = 0; i < 10; i++) i].forEach((element) {
body.add(OpmlOutlineBuilder()
.text('$element 입력입니다.')
.title('$element')
.addChild(OpmlOutlineBuilder().text("👋").title('👋').build())
.build());
});
final opml = OpmlDocument(
head: head,
body: body,
);
final xml = opml.toXmlString(pretty: true);
File file = File('example_out.xml');
file.writeAsString(xml);
print(xml);
}
// write HTML
void writeHTML(String s) {
String htmlTemplate = """
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
__replace__here__
</body>
</html>
""";
String html = htmlTemplate.replaceAll("__replace__here__", s);
final file = File("example.html");
file.writeAsString(html);
}
위의 예제에서는 child의 정보를 가져오기 위해 readChildren() 함수를 재귀적으로 구현했다. 그리고 text에서 MarkDown 문법을 사용했을 경우, 파싱을 하기 위해 markdownToHtml()을 사용했다. 사용한 example_in.xml은 다음과 같다.
4. opml 파일( example_in.xml )
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<opml version="2.0">
<head>
<title>Outline 문서작성을 시작하자</title>
<flavor>dynalist</flavor>
<source>https://dynalist.io</source>
<ownerName>vintage appMaker</ownerName>
<ownerEmail>adsloader99@gmail.com</ownerEmail>
</head>
<body>
<outline text="아웃라인 문서란 ">
<outline text="정보를 계층적 구조로 표현하고 정리하는 방법 "/>
<outline text="아이디어, 개념, 계획, 프로젝트 조직화하고 전달하기 위해 사용"/>
<outline text="아웃라인 문서 작성의 특징">
<outline text="계층적 구조: 아웃라인 문서는 항목을 부모 및 자식 항목으로 구분하여 계층적으로 구조화를 통해 가독성 높임"/>
<outline text="목차 및 서브-목차: 주제와 하위 주제 간의 관계를 명확하게 나타내기 위해 목차와 서브-목차를 사용"/>
<outline text="순차적 맥락: 아웃라인 문서는 항목을 순서대로 나열하고 각 항목을 들여쓰기 등으로 쉽게 전달가능"/>
<outline text="요약: 아웃라인은 많은 텍스트가 있는 내용이라도 구조화된 순서와 맥락을 통해 요약을 하는 효고"/>
</outline>
<outline text="아웃라인 문서의 활용">
<outline text="학습: 정보를 시각화 정리"/>
<outline text="발표 및 강의: Timeline을 기준으로 정보전달 계획 수립에 유리"/>
<outline text="보고서 작성: 핵심내용과 전체흐름을 효과적으로 전달"/>
<outline text="계획: 목표를 향한 Timeline 구성과 맥락(Context)를 구조화"/>
<outline text="<img src='https://img1.daumcdn.net/thumb/C500x500/?fname=http://t1.daumcdn.net/brunch/service/user/4WjL/image/tBiU_abX7taddaBleHfTe-mfkr8.png' />"/>
</outline>
</outline>
<outline text="OPML은 무엇인가?">
<outline text="[OPML의 정의](https://ko.wikipedia.org/wiki/OPML) ">
<outline text="Outline Process Markup langugae"/>
<outline text="아웃라인 형태로 작성된 문서를 표준화한 XML 문서"/>
</outline>
<outline text="OPML(Outline Processor Markup Language) 지원 프로그램">
<outline text="RSS 리더 및 뉴스 어그리게이터:">
<outline text="Feedly"/>
<outline text="Inoreader"/>
<outline text="The Old Reader"/>
<outline text="NewsBlur"/>
<outline text="Reeder (macOS 및 iOS용)"/>
</outline>
<outline text="아웃라인 편집기:">
<outline text="Fargo (웹 기반)"/>
<outline text="OmniOutliner (macOS 및 iOS용)"/>
<outline text="WorkFlowy (웹 기반)"/>
<outline text="dynalist(웹 기반)"/>
</outline>
<outline text="마인드맵:">
<outline text="대부분의 마인드맵 프로그램들"/>
</outline>
</outline>
</outline>
<outline text="아웃라인 문서의 활용법 ">
<outline text="1. 데이터와 프로세스로 설계:">
<outline text="**글쓰기도 프로그래밍과 크게 다르지 않다.** "/>
<outline text="짧고 간결한 프로그래밍 예제를 만드는 것과 유사하다. "/>
<outline text="`전달할 메시지: 데이터(변수와 값)`"/>
<outline text="`글의 흐름(맥락): 함수와 로직`"/>
</outline>
<outline text="2. 설계 후, 코딩">
<outline text="데이터와 맥락을 구조화한 이후"/>
<outline text="항목 별 내용작성">
<outline text="단어정의(변수) ">
<outline text="주제어"/>
<outline text="필수단어 "/>
</outline>
<outline text="흐름구성(변수의 가공)">
<outline text="짧고 쉬운 흐름"/>
<outline text="조건문이 아닌 열거문"/>
<outline text="설명은 극단적으로 최소화"/>
</outline>
<outline text="결과(목적한 메시지전달)">
<outline text="목적한 주제어로 결과 얻기"/>
<outline text="논리적인가? 설득력이 있는가?"/>
</outline>
</outline>
<outline text="내용검수">
<outline text="사용된 단어의 가독성은?(일반용어로 변환가능한가?)"/>
<outline text="불필요한 변수는?(단어의 갯수를 줄이기)"/>
<outline text="불필요한 흐름은?(흐름을 1개로 단순통일하기)"/>
</outline>
</outline>
</outline>
</body>
</opml>
'Source code or Tip > Flutter & Dart' 카테고리의 다른 글
[Flutter] eval과 같은 동적 소스(코드) 처리 (0) | 2024.05.04 |
---|---|
[Dart] 입력값 Validate를 위한 예제 (1) | 2024.04.20 |
[Flutter ]Error: Dart library 'dart:ui' is not available on this platform (0) | 2023.10.21 |
chatGPT의 Open API를 이용한 플러그인 (0) | 2023.03.19 |
Flutter Timer로 스프레쉬 화면에서 메인으로 이동 - pushReplacement (0) | 2023.03.09 |
Comments